rxjssinonrxjs5redux-observablerxjs-dom

Stub catch on redux-observable epic


I`m trying to test the catch function of a rxjs observer but catch never run.

test.js

it.only('On fail restore password', () => {
    sandbox = sinon.stub(Observable.ajax, 'post').returns(new Error());
    store.dispatch(restorePasswordVi('prueba'));
    expect(store.getActions()).toInclude({ success: false, type: SET_RESTORE_PASSWORD_SUCCESS });
  });

Epic please see https://redux-observable.js.org/

export function restorePasswordViEpic(action$: Observable<Action>, store: Store) {
  return action$
    .ofType(RESTORE_PASSWORD_VI)
    .switchMap(({ user }) => {
      store.dispatch(blockLoading(true));
      return Observable
       .ajax
       .post(`${config.host}/auth/restore-password`, { user })
         .map(() => setRestorePasswordSuccess(true))
         .catch(() => {
           return Observable.of(setMessage('Se ha producido un error por favor intente de nuevo.'));
         });
    });
}

Solution

  • Your stubbing of Observable.ajax.post needs to return an Observable that throws the error.

    .returns(Observable.throw(new Error()));
    

    All together:

    it.only('On fail restore password', () => {
      sandbox = sinon.stub(Observable.ajax, 'post').returns(Observable.throw(new Error()));
      store.dispatch(restorePasswordVi('prueba'));
      expect(store.getActions()).toInclude({ success: false, type: SET_RESTORE_PASSWORD_SUCCESS });
    });
    

    Since your existing stub returns just an Error object itself (not an observable that throws an error) it should have caused an uncaught error to be thrown, something like:

    Uncaught TypeError: Observable.ajax.post(...).map is not a function
    

    If you don't see any error like that when you run your test, you may have something swallowing errors silently somewhere, so something to look out for.