Проверка интервала rxjs в компоненте Angular 6 ngOnInit - PullRequest
0 голосов
/ 03 октября 2018

У меня есть компонент со следующей функцией ngOnInit, которая опрашивает сервисный метод для обновления статуса:

ngOnInit() {
  interval(2000).pipe(
    switchMap(() => this.dataService.getStatus())
  ).subscribe((result) => {
    this.uploadStatus = result;
  );
}

Я пытаюсь проверить, что обновления на самом деле происходят, используя следующий код:

beforeEach(() => {
  fixture = TestBed.createComponent(UploadComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});


it('should start checking for status updates', fakeAsync(() => {
  const dataService = TestBed.get(DataService);
  // Mock the getStatus function
  spyOn(dataService, 'getStatus').and.returnValue(Observable.create().pipe(map(() => 'woo')));
  // Should not be initialised yet
  expect(component.uploadStatus).toBeUndefined();
  tick(2000);
  expect(component.uploadStatus).toBe('woo');
}));

Однако component.uploadStatus всегда равно нулю.Как я должен идти о тестировании этого типа сценария?В идеале я хотел бы проверить наличие нескольких обновлений с течением времени.

Спасибо

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Вы можете использовать setTimeout(), чтобы подождать 2 секунды (немного больше, потому что вы снова выполняете асинхронную задачу внутри), а затем проверить значение property.

Обязательно используйте метод done(), чтобы уведомить участника теста о завершении теста.

it('should start checking for status updates', (done) => {
  const dataService = TestBed.get(DataService);
  // Mock the getStatus function
  spyOn(dataService, 'getStatus').and.returnValue(Observable.create().pipe(map(() => 'woo')));
  // Should not be initialised yet
  expect(component.uploadStatus).toBeUndefined();

  setTimeout(()=> {
        expect(component.uploadStatus).toBe('woo');
        done();
  },2500);

});
0 голосов
/ 05 октября 2018

То, на чем я остановился, было следующее.Мне также пришлось сохранить индекс, чтобы я мог отменить его в конце теста, чтобы избежать ошибок «периодические таймеры все еще в очереди»:

ngOnInit() {
  // Store the subscription so we can unsubscribe when testing
  this.pollingSubscription = interval(2000).pipe(
    switchMap(() => this.dataService.getStatus())
  ).subscribe((result) => {
    this.uploadStatus = result;
  });
}

Затем выполните тестирование следующим образом:

it(`init`, fakeAsync(inject([DataService],
  (dataService: DataService) => {
    const testReturns = [
      of('woo'),
      of('yay')
    ];
    let currentReturn = -1;
    spyOn(dataService, 'getStatus').and.callFake(() => {
      currentReturn++;
      return testReturns[currentReturn];
    });

    expect(component.uploadStatus).toBeUndefined();
    fixture.detectChanges();
    // expect(component.uploadStatus).toBe('Login');
    // spyOn(dataService, 'getStatus').and.returnValue(of('woo'));
    component.ngOnInit();
    tick(2000);
    expect(component.uploadStatus).toBe('woo');
    tick(2000);
    expect(component.uploadStatus).toBe('yay');

    // Unsubscribe to prevent the "periodic timers still in queue" errors
    component.pollingSubscription.unsubscribe();
})));
0 голосов
/ 03 октября 2018

Вы должны активировать обнаружение изменений после тика, это должно работать

tick(2000);
fixture.detectChanges();
expect(component.uploadStatus).toBe('woo');
...