loadAdList$
是一个Observable,可以点击actions$
流:
loadAdList$: Observable<Action> = this.actions$
.ofType<adActions.Load>(adActions.LOAD)
.switchMap((action) => {
return Observable.fromPromise(store.findAll('ad', action.payload)
.then((ads) => {
return new adActions.LoadSuccess(ads);
})
.catch((err) => {
return new adActions.LoadFail(err);
}));
});
它在浏览器中运行,没有问题。但是,我也希望对它进行单元测试:
actions$ = hot('-a', { a: loadAction });
const storeResponse = Promise.resolve(mockAds);
const expected$ = cold('-c', { c: loadSuccessAction });
spyOn(store, 'findAll').and.returnValue(storeResponse);
expect(effects.loadAdList$).toBeObservable(expected$);
测试失败并带有以下内容:
Expected
to deep equal
{"frame":10,"notification":{"kind":"N","value":{"payload":"[
...
我认为这个问题与返回承诺的store.findAll
方法有关。这是基于以下测试的结果:
.switchMap((action) => {
// This test will pass
return Observable.from([new adActions.LoadSuccess(mockAds)]);
// This test will fail
return Observable.fromPromise(Promise.resolve(new adActions.LoadSuccess(mockAds)));
});
答案 0 :(得分:8)
有点不幸但是在Rx v5中,在TestScheduler的上下文中,没有很好的方法可以使promise同步解析。出于这些原因,如果Observable源于承诺,它不会使用大理石测试,你必须通过订阅以不同的方式创建断言。
如果您想详细了解其未成功的原因,请检查https://github.com/ReactiveX/rxjs/issues/701 / https://github.com/ReactiveX/rxjs/pull/745。