-
烙印99
RxJS v6对于RxJS v6代码,如下所示:code.jsimport { of } from 'rxjs';import { delay } from 'rxjs/operators';export const example = of('hello').pipe( delay(1000));...您可以使用sinon 伪造的计时器,如下所示:import * as sinon from 'sinon';import { example } from './code';describe('delay', () => { let clock; beforeEach(() => { clock = sinon.useFakeTimers(); }); afterEach(() => { clock.restore(); }); it('should delay one second', () => { const spy = jest.fn(); example.subscribe(spy); expect(spy).not.toHaveBeenCalled(); // Success! clock.tick(1000); expect(spy).toHaveBeenCalledWith('hello'); // Success! });});(请注意,在编写Jest 计时器模拟时不起作用,不确定原因)...或者您可以嘲笑delay不执行以下操作:import { delay } from 'rxjs/operators';import { example } from './code';jest.mock('rxjs/operators', () => { const operators = jest.requireActual('rxjs/operators'); operators.delay = jest.fn(() => (s) => s); // <= mock delay return operators;});describe('delay', () => { it('should delay one second', () => { const spy = jest.fn(); example.subscribe(spy); expect(delay).toHaveBeenCalledWith(1000); // Success! expect(spy).toHaveBeenCalledWith('hello'); // Success! });});RxJS v5对于RxJS v5这样的代码:code.jsimport { Observable } from 'rxjs/Observable';import 'rxjs/add/observable/of';import 'rxjs/add/operator/delay';export const example = Observable.of('hello').delay(1000);...您可以嘲笑delay不执行以下操作:import { Observable } from 'rxjs/Observable';import { example } from './code';jest.mock('rxjs/add/operator/delay', () => { const Observable = require('rxjs/Observable').Observable; Observable.prototype.delay = jest.fn(function () { return this; }); // <= mock delay});describe('delay', () => { it('should delay one second', () => { const spy = jest.fn(); example.subscribe(spy); expect(Observable.prototype.delay).toHaveBeenCalledWith(1000); // Success! expect(spy).toHaveBeenCalledWith('hello'); // Success! });});
-
函数式编程
我们正在使用SchedulerRxjs中的。类看起来像这样:import { Observable, Scheduler, Subject, asapScheduler } from 'rxjs';// ...constructor( @Optional() private readonly _scheduler: Scheduler) { if (isNullOrUndefined(_scheduler)) { this._scheduler = asapScheduler; }}// ...this._someObservable.pipe(delay(1, this._scheduler));然后,在spec文件中提供一个模拟TestModuleMetadata:{ declarations: [YourComponent], imports: [], providers: [ { provide: Scheduler, useValue: new VirtualTimeScheduler() }, ],};现在,您需要做的就是在一个beforeEach块中分配调度程序,并在您希望延迟被“跳过”时刷新它:let schedulerMock = Testbed.get(Scheduler);// ...it('should emit true', () => { let result: boolean = null; comp.someObservable.subscribe(next => (result = next)); schedulerMock.flush(); expect(result).toBe(true);});这也适用于其他时间依赖运算符,例如bufferTime。您要使用或需要在组件中使用哪个调度程序应取决于您的用例,在最佳情况下,请查阅文档并找出最适合您的方案。
-
HUWWW
从版本6.2.1开始,RxJS支持Jest的假时间,因此您可以简单地编写jest.useFakeTimers('modern');test('...', () => { // ...code that subscribes to your observable. jest.runAllTimers(); // ...code that makes assertions.});另外,我已经发布了一个库,使编写这样的测试变得更加容易,这是一个示例(log将日志记录添加到可观察对象中,getMessages检索日志记录的消息):import { getMessages, log } from '1log';import { of } from 'rxjs';import { delay } from 'rxjs/operators';test('delay', () => { of(42).pipe(delay(500), log).subscribe(); jest.runAllTimers(); expect(getMessages()).toMatchInlineSnapshot(` [create 1] +0ms [Observable] [create 1] [subscribe 1] +0ms [Subscriber] [create 1] [subscribe 1] [next] +500ms 42 [create 1] [subscribe 1] [complete] +0ms · [create 1] [subscribe 1] [unsubscribe] +0ms `);});