【问题标题】:Angular unit testing: Function not being called角度单元测试:未调用函数
【发布时间】:2022-01-22 08:43:01
【问题描述】:

我正在尝试对我的服务进行单元测试,但似乎无法使其正常工作。这个概念是当setEmployees() 被一个空数组调用时,服务会从服务器获取员工。

服务

  setEmployees( employees : Employee[] ) {
    console.log("Setting employees...", employees)
    if (employees && employees.length) {
      this.employees.next(employees)
      this.storage.set('employees', employees);
    } else {
      this.getEmployees().subscribe()
    }
  }

  getEmployees() {
    console.log("getting employees...")
    let url = `${this.base_url}/employees`;
    return this.http.get<Employee[]>(url).pipe(
      tap(employees => {
        console.log("got em", employees)
        this.setEmployees(employees)
        this.storage.set('employees', employees)
      })
    )
  }

  returnEmployees() : IEmployee[] {
    return Object.assign([], this.employees.getValue())
  }

测试

it('should set employees correctly', fakeAsync(() => {
  let dummy = [{id: 1, name: 'Jeremy'}, {id: 2, name: 'Paige'}]
  spyOn(employeeService, 'getEmployees').and.returnValue(of(dummy));
  employeeService.setEmployees([]);
  tick();
  expect(employeeService.returnEmployees()).toEqual(dummy)
}))

测试响应

Expected $.length = 0 to equal 2.
Expected $[0] = undefined to equal Object({ id: 1, name: 'Jeremy' }).
Expected $[1] = undefined to equal Object({ id: 2, name: 'Paige' }).

还值得注意的是,console.log() 语句未按预期顺序出现。运行此测试时,我在控制台中看到以下内容:

getting employees...
Setting employees... []

...当我期望看到时:

Setting employees... []
getting employees...
got em [{id: 1, name: 'Jeremy'}, {id: 2, name: 'Paige'}]
Setting employees... [{id: 1, name: 'Jeremy'}, {id: 2, name: 'Paige'}]

显然有些东西没有按预期触发,但我不确定问题出在哪里。

【问题讨论】:

  • 在您的服务中,this.employees.getValue() 中“员工”的定义是什么?
  • employees = new BehaviorSubject(&lt;IEmployee[]&gt;[]); employees$ = this.employees.asObservable()

标签: angular unit-testing karma-jasmine


【解决方案1】:

异步函数的测试有一些问题,你的截图似乎容易受到其中一些的影响...... 我建议更标准地使用 Observables。并使用ReplaySubject 在服务中保留最新的员工数组值。类似的东西:

服务:

employees$ = new ReplaySubject<Employee[]>(); 

setEmployees( employees : Employee[] ) {
  if (employees && employees.length) {
    this.employees$.next(employees)
  } else {
    this.getEmployees()
  }
}

getEmployees() {
  let url = `${this.base_url}/employees`;
  return this.http.get<Employee[]>(url).pipe(take(1))
         .subscribe(employees => this.employees$.next(employees))
}

你的测试:

it('should set employees correctly', done => { // the 'done' helper function ensures necessary async callbacks are waited for
  let dummy = [{id: 1, name: 'Jeremy'}, {id: 2, name: 'Paige'}]

  employeeService.setEmployees(dummy)

  employeeService.employees$.subscribe(employees => {
    expect(employees).toEqual(dummy) // you might want to do a better element comparison here
    done()
  })
}))

【讨论】:

  • Hmm .. 执行此操作后,我仍然以错误的顺序显示 console.logs 并且测试失败。您订阅中employees 的值为空。
  • 抱歉,错过了 getEmployees() 上的“返回”...现在更新了
猜你喜欢
  • 2018-06-25
  • 2016-08-07
  • 2021-11-12
  • 2019-11-20
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多