代码之家  ›  专栏  ›  技术社区  ›  Jeremy Thomas

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

  •  0
  • Jeremy Thomas  · 技术社区  · 4 年前

    我试图对我的服务进行单元测试,但似乎无法使其正常工作。概念是当 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'}]
    

    很明显,有些事情并没有像预期的那样发生,但我不确定问题出在哪里。

    0 回复  |  直到 4 年前
        1
  •  0
  •   The Fabio    4 年前

    异步函数的测试有几个陷阱,你的被剪掉的部分似乎很容易受到影响。。。 我建议使用更标准的可观测值。使用 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()
      })
    }))