У меня есть угловой компонент, который опрашивает новые данные, и пока мы ждем ответа, он обновляет сообщение в пользовательском интерфейсе каждые X секунд.Он циклически перебирает простой строковый массив сообщений для показа.
После получения правильных данных мы переходим на соответствующую страницу.
this.pollSubscription = timer(0, pollTimeInSeconds)
.pipe(
//convert each observable iteration into an interval in seconds
map((count: number) => count * pollTimeInSeconds),
//keep going if we are below the max poll time
takeWhile((time: number) => time < this.maxPollTime),
//update the UI message
tap((time: number) => this.updateCurrentMessage(time)),
//
switchMap(() => this.getDataOrError$())
)
.subscribe(
//navigate to the correct page
(d: IData) => this.navigateBasedOnStatus(d),
//If an error occurs, OR the observable completes (which should not happen), navigate to the error page
() => this.navigateToError(),
() => this.navigateToError()
);
Я хочу проверить это поведение, но яЯ не совсем уверен, как издеваться timer
для этой ситуации.Я видел этот SO-ответ , но я не смог заставить это работать в моей ситуации.
В идеале я хотел бы структурировать тест примерно так, чтобы каждое сообщение показывалось ичто, если таймер идет дольше, чем ожидалось, он возвращается к первому сообщению:
it('should show every status as the timer changes', fakeAsync(() => {
tick(0);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message one');
tick(1000);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message two');
tick(2000);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message three');
//etc...
}));
РЕДАКТИРОВАТЬ Я включаю новую попытку тестирования этого на основе некоторых комментариевниже, но это все еще не работает
let timerTick: (milliseconds: number) => void;
beforeEach(() => {
let fakeNow = 0;
timerTick = (milliseconds: number): void => {
fakeNow += milliseconds;
tick(milliseconds);
};
asyncScheduler.now = (): number => fakeNow;
});
afterEach(() => {
delete asyncScheduler.now;
});
it('should show every status as the timer changes', fakeAsync(() => {
fixture.detectChanges(); // triggers ngOnInit()
const pollTimeInSeconds = loginPollTime * 1000;
let received: number | undefined;
timer(0, pollTimeInSeconds, asyncScheduler).subscribe((value: number) => received = value);
console.log(received);
timerTick(0);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message one');
console.log(received)
timerTick(pollTimeInSeconds);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message two');
console.log(received)
timerTick(pollTimeInSeconds * 2);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message three');
console.log(received)
}));
Жасминовый вывод:
Expected 'Message one' to equal 'Message two'.
Expected 'Message one' to equal 'Message three'.
Консольный вывод:
> undefined
> 0
> 1
> 3