为什么jest.useFakeTimers不能使用RxJs Observable延迟 [英] Why is jest.useFakeTimers not working with RxJs Observable delay

查看:631
本文介绍了为什么jest.useFakeTimers不能使用RxJs Observable延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么 jest.useFakeTimers 正在使用 setTimeout 但不能使用RxJs的延迟运算符:

I'm wondering why jest.useFakeTimers is working with setTimeout but not with the delay operator of 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()使测试过去

FYI: using 20 or 2000 as an argument for jest.runTimersToTime makes no difference. Using jest.runAllTimers() makes the test past

推荐答案

延迟运算符不适用于Jest的假定时器,因为延迟运算符的实现使用其调度程序的时间概念 - 这与Jest的假时间概念无关。

The delay operator does not work with Jest's fake timers because the delay operator's implementation uses its scheduler's concept of time - which is unrelated to Jest's concept of fake time.

来源是这里

while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
  queue.shift().notification.observe(destination);
}

当创建通知时,会将当前(非假)时间分配给通知当前时间是调度程序的 now 方法返回的时间。当使用Jest的假定时器时,实际(非假)时间量将不足,通知将保留在队列中。

The current (non-fake) time is assigned to notifications when they are created and the current time is what the scheduler's now method returns. When Jest's fake timers are used, an insufficient amount of actual (non-fake) time will have elapsed and the notifications will remain in the queue.

使用写入RxJS测试假的或虚拟的时间,你可以使用 VirtualTimeScheduler 。请参阅此答案。或者您可以使用 TestScheduler 大理石测试

To write RxJS tests using fake or virtual time, you can use the VirtualTimeScheduler. See this answer. Or you can use the TestScheduler and marble tests.

这篇关于为什么jest.useFakeTimers不能使用RxJs Observable延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆