У меня есть служба angular, задача которой - опрашивать API каждые 60 секунд, чтобы проверить, подключен ли клиент по-прежнему:
export class AppService {
get isOnline$(): Observable<{ online: boolean }> {
return this.isOnlineSource.asObservable();
}
private isOnlineSource = new BehaviorSubject<{ online: boolean }>({ online: true });
constructor(private http: HttpClient) {
timer(0, 60000).switchMap(() =>
this.http.get(`${environment.apiUrl}/api/assessments/amionline`, environment.httpOptions)
.map(x => {
return { online: true };
})
.catch((err, caught) => {
return of({ online: false });
})
).
subscribe(data => this.isOnlineSource.next(data));
}
}
Как мне протестировать этот код? Я думал, что блока fakeAsync с тиком () будет достаточно для запуска наблюдаемого, но httpMock не получает запросов
Код теста:
it('should return online equals false.', fakeAsync(() => {
appService.isOnline$.subscribe(data => {
expect(data.online).toEqual(false);
});
tick(70000);
httpMock.expectOne(url).flush(undefined, mockErrorResponse);
httpMock.verify();
}));
});
Примечание: в тесте используется HttpClientTestingModule, а httpMock - HttpTestingController.
Что это значит, что вызов fakeAsync () и tick () - нет?
Он исправляет планировщики, так что RxJS использует ту же концепцию фиктивного времени, что и zone.js. По сути, это просто заставляет RxJS хорошо работать с fakeAsync, который он вызывает внутри себя.





Проблема, мешающая вашему тесту работать, решена в этот пиар, который недавно был объединен.
fakeAsync Angular исправляет функции, связанные со временем, такие как setTimeout, а также исправляет класс Date, в частности, исправляет Date.now. К сожалению, до того, как PR был объединен, RxJS использовал ссылку на Date.now, прежде чем он мог быть исправлен с помощью fakeAsync.
Это означает, что ваш тест будет работать, когда будет опубликован следующий выпуск RxJS.
До тех пор вы могли либо использовать функцию fakeSchedulers в моем пакете rxjs-marbles, либо использовать аналогичную технику для исправления метода now планировщика. (Угловая реализация fakeSchedulers прост.)
Если вы используете RxJS версии 5, есть альтернатива: вы можете импортировать zone-patch-rxjs-fake-async.js и указать zone.js для исправления планировщиков. Просто добавьте import 'zone.js/dist/zone-patch-rxjs-fake-async' в ваш файл src/test.ts.
Спасибо за добавленное объяснение. К сожалению, теперь я получаю «TypeError: Невозможно преобразовать undefined или null в объект», и я не могу понять, откуда это взялось.
Какие версии Angular и RxJS вы используете?
Угловой 5.2.11 и RxJS 5.5.11
fakeSchedulers существует только в версии rxjs-marbles, которая поддерживает RxJS версии 6. Однако есть альтернатива: исправить планировщики с помощью zone.js. Я обновил ответ.
Взгляните на github.com/cartant/rxjs-marbles/blob/master/…