loadAdList$
is an Observable that taps into the actions$
stream:
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);
}));
});
It works in the browser, there is no problem with it. However, I want to unit test it as well:
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$);
The test fails with the following:
Expected
to deep equal
{"frame":10,"notification":{"kind":"N","value":{"payload":"[
...
I believe the issue has something to do with the store.findAll
method returning a promise. This is based on the results of the following test:
.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)));
});
It is bit unfortunate but there wasn't great way to make promise resolves synchronously under context of TestScheduler in Rx v5. For those reason, if Observable source started off from promise it won't work with marble testings and you have to create assertion differently by subscribing.
Check https://github.com/ReactiveX/rxjs/issues/701 / https://github.com/ReactiveX/rxjs/pull/745 if you'd like to have detail why it wasn't successful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With