猿问

用Jest模拟delay()RxJS

有没有简单的方法可以模拟delay()RxJS的方法,例如在虚假的时间观察?


我有这种方法:


register(user) {

  return this._checkLog(user).delay(500).flatMap( ... )

}

当我删除delay()方法时,从_register()进行的测试全部成功。


跃然一笑
浏览 259回答 3
3回答

烙印99

RxJS v6对于RxJS v6代码,如下所示:code.jsimport { of } from 'rxjs';import { delay } from 'rxjs/operators';export const example = of('hello').pipe(&nbsp; delay(1000));...您可以使用sinon 伪造的计时器,如下所示:import * as sinon from 'sinon';import { example } from './code';describe('delay', () => {&nbsp; let clock;&nbsp; beforeEach(() => { clock = sinon.useFakeTimers(); });&nbsp; afterEach(() => { clock.restore(); });&nbsp; it('should delay one second', () => {&nbsp; &nbsp; const spy = jest.fn();&nbsp; &nbsp; example.subscribe(spy);&nbsp; &nbsp; expect(spy).not.toHaveBeenCalled();&nbsp; // Success!&nbsp; &nbsp; clock.tick(1000);&nbsp; &nbsp; expect(spy).toHaveBeenCalledWith('hello');&nbsp; // Success!&nbsp; });});(请注意,在编写Jest 计时器模拟时不起作用,不确定原因)...或者您可以嘲笑delay不执行以下操作:import { delay } from 'rxjs/operators';import { example } from './code';jest.mock('rxjs/operators', () => {&nbsp; const operators = jest.requireActual('rxjs/operators');&nbsp; operators.delay = jest.fn(() => (s) => s);&nbsp; // <= mock delay&nbsp; return operators;});describe('delay', () => {&nbsp; it('should delay one second', () => {&nbsp; &nbsp; const spy = jest.fn();&nbsp; &nbsp; example.subscribe(spy);&nbsp; &nbsp; expect(delay).toHaveBeenCalledWith(1000);&nbsp; // Success!&nbsp; &nbsp; expect(spy).toHaveBeenCalledWith('hello');&nbsp; // Success!&nbsp; });});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', () => {&nbsp; const Observable = require('rxjs/Observable').Observable;&nbsp; Observable.prototype.delay = jest.fn(function () { return this; });&nbsp; // <= mock delay});describe('delay', () => {&nbsp; it('should delay one second', () => {&nbsp; &nbsp; const spy = jest.fn();&nbsp; &nbsp; example.subscribe(spy);&nbsp; &nbsp; expect(Observable.prototype.delay).toHaveBeenCalledWith(1000);&nbsp; // Success!&nbsp; &nbsp; expect(spy).toHaveBeenCalledWith('hello');&nbsp; // Success!&nbsp; });});

函数式编程

我们正在使用SchedulerRxjs中的。类看起来像这样:import { Observable, Scheduler, Subject, asapScheduler } from 'rxjs';// ...constructor(&nbsp; &nbsp; @Optional() private readonly _scheduler: Scheduler) {&nbsp; &nbsp; if (isNullOrUndefined(_scheduler)) {&nbsp; &nbsp; &nbsp; &nbsp; this._scheduler = asapScheduler;&nbsp; &nbsp; }}// ...this._someObservable.pipe(delay(1, this._scheduler));然后,在spec文件中提供一个模拟TestModuleMetadata:{&nbsp; &nbsp; declarations: [YourComponent],&nbsp; &nbsp; imports: [],&nbsp; &nbsp; providers: [&nbsp; &nbsp; &nbsp; &nbsp; { provide: Scheduler, useValue: new VirtualTimeScheduler() },&nbsp; &nbsp; ],};现在,您需要做的就是在一个beforeEach块中分配调度程序,并在您希望延迟被“跳过”时刷新它:let schedulerMock = Testbed.get(Scheduler);// ...it('should emit true', () => {&nbsp; &nbsp; let result: boolean = null;&nbsp; &nbsp; comp.someObservable.subscribe(next => (result = next));&nbsp; &nbsp; schedulerMock.flush();&nbsp; &nbsp; expect(result).toBe(true);});这也适用于其他时间依赖运算符,例如bufferTime。您要使用或需要在组件中使用哪个调度程序应取决于您的用例,在最佳情况下,请查阅文档并找出最适合您的方案。

HUWWW

从版本6.2.1开始,RxJS支持Jest的假时间,因此您可以简单地编写jest.useFakeTimers('modern');test('...', () => {&nbsp; // ...code that subscribes to your observable.&nbsp; jest.runAllTimers();&nbsp; // ...code that makes assertions.});另外,我已经发布了一个库,使编写这样的测试变得更加容易,这是一个示例(log将日志记录添加到可观察对象中,getMessages检索日志记录的消息):import { getMessages, log } from '1log';import { of } from 'rxjs';import { delay } from 'rxjs/operators';test('delay', () => {&nbsp; of(42).pipe(delay(500), log).subscribe();&nbsp; jest.runAllTimers();&nbsp; expect(getMessages()).toMatchInlineSnapshot(`&nbsp; &nbsp; [create 1] +0ms [Observable]&nbsp; &nbsp; [create 1] [subscribe 1] +0ms [Subscriber]&nbsp; &nbsp; [create 1] [subscribe 1] [next] +500ms 42&nbsp; &nbsp; [create 1] [subscribe 1] [complete] +0ms&nbsp; &nbsp; · [create 1] [subscribe 1] [unsubscribe] +0ms&nbsp; `);});
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答