Поскольку вы используете fakeAsync
, вы можете положиться на его исправление setInterval
, чтобы подделать реализацию наблюдаемой timer
.
Однако вам нужно будет заткнуть экземпляр asyncScheduler
now
метод, поскольку он возвращает Date.now()
.(Строго говоря, это не обязательно для timer
наблюдаемой, как вы ее использовали, но это будет иметь значение для некоторых других наблюдаемых - например, наблюдаемая, возвращаемая оператором delay
).
Вы можете заставить вещи работать довольно легко, если вы используете beforeEach
и afterEach
для подавления метода now
и для настройки функции, которая отслеживает фальшивое время:
import { fakeAsync, tick as _tick } from '@angular/core/testing';
import { asyncScheduler, of, timer } from 'rxjs';
import { delay } from 'rxjs/operators';
describe('fakeAsync and RxJS', () => {
let tick: (milliseconds: number) => void;
beforeEach(() => {
let fakeNow = 0;
tick = milliseconds => {
fakeNow += milliseconds;
_tick(milliseconds);
};
asyncScheduler.now = () => fakeNow;
});
it('should support timer with fakeAsync', fakeAsync(() => {
const source = timer(100);
let received: number | undefined;
source.subscribe(value => received = value);
tick(50);
expect(received).not.toBeDefined();
tick(50);
expect(received).toBe(0);
}));
it('should support delay with fakeAsync', fakeAsync(() => {
const source = of(0).pipe(delay(100));
let received: number | undefined;
source.subscribe(value => received = value);
tick(50);
expect(received).not.toBeDefined();
tick(50);
expect(received).toBe(0);
}));
afterEach(() => {
delete asyncScheduler.now;
});
});
На самом деле, поскольку полагаться на fakeAsync
для имитации наблюдаемой на основе времени вероятности будет полезно, я добавил функцию fakeSchedulers
в свой пакет rxjs-marbles
.См., Например, fake-spec.ts
.
Реализация в основном такая же, как в приведенном выше фрагменте - только что обернута в функцию.
Так какнаписав этот ответ и добавив fakeSchedulers
к rxjs-marbles
, я написал статью о тестировании с поддельным временем .