Почему jest.useFakeTimers не работает с RxJs Наблюдаемая задержка
Мне интересно почему jest.useFakeTimers
работает с setTimeout
но не с оператором задержки RxJs:
jest.useFakeTimers();
import {Observable} from 'rxjs/Observable';
import 'rxjs';
describe('timers', () => {
it('should resolve setTimeout synchronously', () => {
const spy = jest.fn();
setTimeout(spy, 20);
expect(spy).not.toHaveBeenCalled();
jest.runTimersToTime(20);
expect(spy).toHaveBeenCalledTimes(1);
});
it('should resolve setInterval synchronously', () => {
const spy = jest.fn();
setInterval(spy, 20);
expect(spy).not.toHaveBeenCalled();
jest.runTimersToTime(20);
expect(spy).toHaveBeenCalledTimes(1);
jest.runTimersToTime(20);
expect(spy).toHaveBeenCalledTimes(2);
});
it('should work with observables', () => {
const delay$ = Observable.of(true).delay(20);
const spy = jest.fn();
delay$.subscribe(spy);
expect(spy).not.toHaveBeenCalled();
jest.runTimersToTime(2000);
expect(spy).toHaveBeenCalledTimes(1);
});
});
К вашему сведению: используя 20 или 2000 в качестве аргумента для jest.runTimersToTime
не имеет значения. С помощью jest.runAllTimers()
проходит испытание
1 ответ
delay
оператор не работает с поддельными таймерами Джеста, потому что delay
Реализация оператора использует концепцию времени своего планировщика, которая не связана с концепцией фальшивого времени Джеста.
Источник здесь:
while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
queue.shift().notification.observe(destination);
}
Текущее (не поддельное) время присваивается уведомлениям при их создании, а текущее время - это то, что планировщик now
метод возвращает. Когда используются ложные таймеры Jest, фактическое (не поддельное) время истечет, а уведомления останутся в очереди.
Чтобы написать тесты RxJS, используя поддельное или виртуальное время, вы можете использовать VirtualTimeScheduler
, Смотрите этот ответ. Или вы можете использовать TestScheduler
и мраморные тесты.