I'm pretty new to redux-observable so I'm not sure whether is a real problem or just a silly mistake.
I'm trying to add test to a epics I wrote for a React applications, but I'm not able to test them. This is the example.
My example epic:
const example = action$ =>
action$.pipe(
ofType('my_type'),
mergeMap(() => {
return { type: 'result_type'}
})
);
I was trying to test it in the simplest possible way:
it('simple test', done => {
const action$ = ActionsObservable.of({ type: 'my_type'});
const state$ = null;
return myEpics.example(action$, state$)
.subscribe(actions => {
expect(actions).toEqual({ type: 'result_type'});
done();
})
});
Using this code I get the following error:
TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
12 |
13 | return myEpics.example(action$, state$)
> 14 | .subscribe(actions => {
| ^
I'm using redux-observable 1.2.0, rxjs 6.5.3
Did I miss something? I saw many examples of this type and they work.
EDIT
What I'm really doing (apart from the dummy example) is replacing a redux-thunk promise-based api middleware (with many async call to a ReST endpoint). I was able to make it work, but about testing I'm a little bit confused. I saw the marble-diagram approach, and the subscribe-to-epic one adding expectations e.g. on api calls, resulting actions. I'm using the latter, but, for example, for an epic returning multiple actions, I get only the first one in the subscribe.
A 'complex' example:
export const handleLogIn = (action$, state$) =>
action$.pipe(
ofType(authTypes.LOG_IN),
withLatestFrom(state$),
mergeMap(([{ payload: credentials}, { router }]) =>
from(ApiService.logIn(credentials))
.pipe(
mergeMap(authToken => of(authActions.set_auth_token(authToken), navigationActions.goTo(router.location.state ? router.location.state.pathname : baseRoutes.START),
catchError(message => of(authActions.set_auth_error(message)))
)
)
);
Test
it('should handle LOG_IN navigating to base path', done => {
const token = 'aToken';
const credentials = { username: 'user', password: 'password' };
const action$ = ActionsObservable.of(authActions.log_in(credentials));
const state$ = new StateObservable(new Subject(), { router: { location: { state: null }}});
spyOn(ApiService, 'logIn').and.returnValue(Promise.resolve(token));
authEpics.handleLogIn(action$, state$)
.subscribe(actions => {
expect(ApiService.logIn).toHaveBeenCalledWith(credentials);
expect(actions).toEqual([
authActions.set_auth_token(token),
navigationActions.go_to(baseRoutes.START)
]);
done();
});
});
the test fails because only authActions.set_auth_token is the only action returned. Am I missing something?