3 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊
RxJS v6
對(duì)于RxJS v6代碼,如下所示:
code.js
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
export const example = of('hello').pipe(
delay(1000)
);
...您可以使用sinon 偽造的計(jì)時(shí)器,如下所示:
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!
});
});
(請(qǐng)注意,在編寫(xiě)Jest 計(jì)時(shí)器模擬時(shí)不起作用,不確定原因)
...或者您可以嘲笑delay不執(zhí)行以下操作:
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
對(duì)于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不執(zhí)行以下操作:
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!
});
});

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊
我們正在使用SchedulerRxjs中的。
類(lèi)看起來(lái)像這樣:
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文件中提供一個(gè)模擬TestModuleMetadata:
{
declarations: [YourComponent],
imports: [],
providers: [
{ provide: Scheduler, useValue: new VirtualTimeScheduler() },
],
};
現(xiàn)在,您需要做的就是在一個(gè)beforeEach塊中分配調(diào)度程序,并在您希望延遲被“跳過(guò)”時(shí)刷新它:
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);
});
這也適用于其他時(shí)間依賴(lài)運(yùn)算符,例如bufferTime。您要使用或需要在組件中使用哪個(gè)調(diào)度程序應(yīng)取決于您的用例,在最佳情況下,請(qǐng)查閱文檔并找出最適合您的方案。

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個(gè)贊
從版本6.2.1開(kāi)始,RxJS支持Jest的假時(shí)間,因此您可以簡(jiǎn)單地編寫(xiě)
jest.useFakeTimers('modern');
test('...', () => {
// ...code that subscribes to your observable.
jest.runAllTimers();
// ...code that makes assertions.
});
另外,我已經(jīng)發(fā)布了一個(gè)庫(kù),使編寫(xiě)這樣的測(cè)試變得更加容易,這是一個(gè)示例(log將日志記錄添加到可觀察對(duì)象中,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
`);
});
添加回答
舉報(bào)