角度单元测试:未调用函数

Posted

技术标签:

【中文标题】角度单元测试:未调用函数【英文标题】: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() 【参考方案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() 上的“返回”...现在更新了

以上是关于角度单元测试:未调用函数的主要内容,如果未能解决你的问题,请参考以下文章

在单元测试中验证函数调用顺序

Unity 单元测试 - 检查带有参数的函数调用是不是引发异常

用于链式函数调用的 Jest 单元测试

如何在单元测试中使用 argparse 参数调用函数?

致命错误:调用未定义函数 openssl_random_pseudo_bytes()

Angular - 单元测试间谍无法识别该函数已被调用