blo*_*ork 3 javascript unit-testing rxjs jestjs asynctest
我想知道为什么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);
});
});
Run Code Online (Sandbox Code Playgroud)
仅供参考:使用20或2000作为参数jest.runTimersToTime
没有任何区别.使用jest.runAllTimers()
使测试过去
的delay
,因为运营商不与玩笑的假定时器工作delay
是无关的假时间玩笑的概念-运营商实现使用时间的调度的概念.
来源在这里:
while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
queue.shift().notification.observe(destination);
}
Run Code Online (Sandbox Code Playgroud)
当前(非假)时间在创建时分配给通知,并且当前时间是调度程序now
方法返回的时间.当使用Jest的假定时器时,实际(非假)时间量将不足,通知将保留在队列中.
要使用假或虚拟时间编写RxJS测试,您可以使用VirtualTimeScheduler
.看到这个答案.或者你可以使用TestScheduler
和大理石测试.