为了账号安全,请及时绑定邮箱和手机立即绑定

用Jest模拟delay()RxJS

用Jest模拟delay()RxJS

跃然一笑 2021-04-01 12:14:50
有没有简单的方法可以模拟delay()RxJS的方法,例如在虚假的时间观察?我有这种方法:register(user) {  return this._checkLog(user).delay(500).flatMap( ... )}当我删除delay()方法时,从_register()进行的测试全部成功。
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

RxJS v6

对于RxJS v6代码,如下所示:


code.js


import { 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.js


import { 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!

  });

});


查看完整回答
反对 回复 2021-04-22
?
函数式编程

TA贡献1807条经验 获得超9个赞

我们正在使用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。您要使用或需要在组件中使用哪个调度程序应取决于您的用例,在最佳情况下,请查阅文档并找出最适合您的方案。


查看完整回答
反对 回复 2021-04-22
?
HUWWW

TA贡献1874条经验 获得超12个赞

从版本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

  `);

});


查看完整回答
反对 回复 2021-04-22
  • 3 回答
  • 0 关注
  • 258 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信