Почему 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 и мраморные тесты.

Другие вопросы по тегам