我们最近从 Angular 5 更新到 Angular 6,并随之更新为 RxJs 6。
作为迁移的一部分,计时器的使用已更改为:
Observable.timer()
to
timer()
在我们的测试中有很多地方我们使用以下模式模拟计时器可观察值。
let timerObserver: Observer<any>;
beforeEach(() => {
spyOn(Observable, 'timer').and.returnValue(Observable.create(
((observer: Observer<any>) => {
timerObserver = observer;
})
));
});
it(`should not have any notifications by default`, () => {
timerObserver.next('');
...
});
有人知道如何迁移这种模式吗?
Edit:我在这里创建了问题的简化说明:
https://stackblitz.com/edit/angular-v6-testing-template-nm7add
// Hello.Component
ngOnInit() {
const timer$ = timer(30);
timer$.subscribe(() => {
this.testMe = 'this has been changed';
});
}
// Hello.component.spec
it('should set testMe after a given timer', fakeAsync(() => {
tick(50);
expect(fixture.componentInstance.testMe).toBe('this has been changed');
}));
在此示例中,我尝试让计时器触发,而不等待计时器解析。
当你正在使用fakeAsync
,你可以依赖它的补丁setInterval
伪造实施timer
可观察到的。
但是,您需要破坏asyncScheduler
实例的now
方法,当它返回时Date.now()
。 (严格来说,这对于timer
observable,正如您使用过的那样,但对于其他一些 observable 来说这很重要 - 例如返回的可观察量delay
操作员)。
如果你使用的话,你可以很容易地让事情开始工作beforeEach
and 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
to rxjs-marbles
,我写过一篇关于使用假时间进行测试.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)