在调用组件中的异步服务之前测试是否正确设置了值

时间:2016-11-18 15:57:27

标签: testing angular asynchronous jasmine

我正在为Angular2应用编写单元测试,其中一个组件在初始化时为了加载其数据而调用异步服务。在加载数据之前,应该将loading标记设置为true以显示微调器,然后一旦数据已经将loading标志设置回false检索。

ngOnInit() {
  this.reloadEmployees(this.filter);
}

reloadEmployees(filter: string) {
  this.loading = true;
  this.employeeService.getEmployees(filter).subscribe((results: Employee[]) => {
    this.employees = results;
    this.loading = false;
  });
} 

以下是我编写测试的方式:

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [EmployeeComponent],
    imports: [FormsModule, SpinnerModule, ModalModule, TranslateModule.forRoot()],
    providers: [
      { provide: EmployeeService, useValue: employeeServiceStub },
    ]
  });

  fixture = TestBed.createComponent(EmployeeComponent);
  component = fixture.componentInstance;
  let employeeService = fixture.debugElement.injector.get(EmployeeService);
  spy = spyOn(employeeService, 'getEmployees').and.returnValue(Observable.of(testEmployees));
});

it('should start loading employees when the component is initialized', fakeAsync(() => {
  fixture.detectChanges();
  expect(component.loading).toEqual(true);
}));

我希望只有在我的测试中调用tick()时才能运行来自服务的回调,但显然它仍然被调用,因为当我检查时component.loading已经回到false它的价值。请注意,如果我在组件的回调中注释掉将loading设置为false的行,则测试通过。

知道我该如何测试吗?

1 个答案:

答案 0 :(得分:2)

Rx.Observable.of似乎是同步的(GitHub issue)。这就是为什么fakeAsync包装器无法使用它。

相反,您可以使用例如Observable.fromPromise(Promise.resolve(...))

在你的情况下:

spy = spyOn(employeeService, 'getEmployees').and.returnValue(
  Observable.fromPromise(Promise.resolve(testEmployees)));

或者,您可以使用async scheduler

import { Scheduler } from 'rxjs/Rx';
...
spy = spyOn(employeeService, 'getEmployees').and.returnValue(
  Observable.of(testEmployees, Scheduler.async));

我已在Plunkr

上准备了一份工作测试样本