用Jest模拟delay()RxJS

Duj*_*ard 6 javascript unit-testing rxjs jestjs

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

我有这种方法:

register(user) {
  return this._checkLog(user).delay(500).flatMap( ... )
}
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*ams 5

RxJS v6

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

code.js

import { of } from 'rxjs';
import { delay } from 'rxjs/operators';

export const example = of('hello').pipe(
  delay(1000)
);
Run Code Online (Sandbox Code Playgroud)

...您可以像这样使用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!
  });
});
Run Code Online (Sandbox Code Playgroud)

(请注意,在编写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!
  });
});
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

...您可以嘲笑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!
  });
});
Run Code Online (Sandbox Code Playgroud)