I followed the steps from documentation to test epic.
...
store.dispatch({ type: FETCH_USER });
expect(store.getActions()).toEqual([
{ type: FETCH_USER },
{ type: FETCH_USER_FULFILLED, payload }
]);
...
But I get failed because second action is been received some later like following.
Test failed
Expected value to equal:
[{"type": "FETCH_USER"}, {"type": "FETCH_USER_FULFILLED", "payload": [some]}]
Received:
[{"type": "FETCH_USER"}]
Difference:
- Expected
+ Received
@@ -1,20 +1,5 @@
Array [
Object {"type": "FETCH_USER"},
Object {"type": "FETCH_USER_FULFILLED", "payload": [some]} ] // this is what should be.
So I think I should know when the dispatch is finished or some like that. How can I solve this?
I used fetch() and Rx.Observable.fromPromise instead of ajax.getJSON()
Here is my epic.
const fetchUserEpic = (action$) =>
action$
.ofType(FETCH_USER)
.mergeMap(() => {
return Rx.Observable.fromPromise(api.fetchUser())
.map((users) => ({
type: FETCH_USER_FULFILLED,
payload: { users }
}))
.catch((error) => Rx.Observable.of({
type: FETCH_USER_ERROR,
payload: { error }
}))
.takeUntil(action$.ofType(FETCH_USER_CANCELLED))
})
The reason is that promises always resolve on the next microtask so your
api.fetchUser()
isn't emitting synchronously.You'll need to either mock it out, use something like
Promise.resolve().then(() => expect(store.getActions).toEqual(...)
to wait until the next microtask, or you can experiment with testing your epics directly without using redux.This will be our preferred testing story in the docs when I (or someone else) has time to write them up. So instead of using redux and the middleware in your tests, we just call the epic function directly with our own mocks. Much easier and cleaner.
With that approach, we can leverage the new dependency injection feature of redux-observable: https://redux-observable.js.org/docs/recipes/InjectingDependenciesIntoEpics.html
First, use isomorphic-fetch instead of Observable.ajax for nock support, like this
So my epic is:
Then, you may need an interval to decide when to finish the test.
enjoy it :)