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

查看:24
本文介绍了为什么 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

推荐答案

delay 运算符不适用于 Jest 的伪计时器,因为 delay 运算符的实现使用了其调度程序的概念时间 - 这与 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天全站免登陆