Недавно мы обновили Angular 5 до Angular 6, а вместе с ним и RxJs 6. В рамках миграции использование таймера изменилось с:
Observable.timer()
to
timer()
В наших тестах есть несколько мест, где мы имитируем наблюдаемые значения таймера по следующему шаблону.
let timerObserver: Observer<any>;
beforeEach(() => {
spyOn(Observable, 'timer').and.returnValue(Observable.create(
((observer: Observer<any>) => {
timerObserver = observer;
})
));
});
it(`should not have any notifications by default`, () => {
timerObserver.next('');
...
});
Кто-нибудь знает, как перенести этот шаблон?
Изменить: я создал упрощенную иллюстрацию проблемы здесь:
https://stackblitz.com/edit/angular-v6-testing-template-nm7add
// Hello.Component
ngOnInit() {
const timer$ = timer(30);
timer$.subscribe(() => {
this.testMe = 'this has been changed';
});
}
// Hello.component.spec
it('should set testMe after a given timer', fakeAsync(() => {
tick(50);
expect(fixture.componentInstance.testMe).toBe('this has been changed');
}));
В этом примере я пытаюсь запустить таймер, не дожидаясь разрешения таймера.
VirtualTimeScheduler
. См. этот ответ. Или, что еще лучше, используйте мраморный тест. - person cartant   schedule 08.06.2018fakeAsync
, вы можете положиться на то, что он имитируетsetInterval
— это то, что RxJS использует в своемAsyncScheduler
— но вам нужно будет стереть методnow
asyncScheduler
, чтобы вернуть концепциюfakeAsync
о текущем времени. См. этот ответ для механизма стирания. (Хотяasync
теперь называетсяasyncScheduler
.) Разблокированныйnow
будет называтьсяDate.now()
и это не будет работать сfakeAsync
. - person cartant   schedule 09.06.2018