Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing catch block via jest mock

I'm trying to test the 'catch' block of an async redux action via jest, but throwing a catch in the mock causes the test as a whole to fail.

My action is as follows:

export function loginUser(username, password) {
  return async dispatch => {
    dispatch({type: UPDATE_IN_PROGRESS});
    try {
      let response = await MyRequest.postAsync(
        '/login', {username: username, password: password}
      );
      dispatch({
        type: USER_AUTHENTICATED,
        username: response.username,
        token: response.token,
        role: response.role,
        id: response.id
      });
    } catch (error) {
      dispatch({type: USER_SIGNED_OUT});
      throw error;
    } finally {
      dispatch({type: UPDATE_COMPLETE});
    }
  };
}

The test is trying to mock up 'MyRequest.postAsync' to throw an error and thus trigger the catch block, but the test just bails with a 'Failed' message

it('calls expected actions when failed log in', async() => {
  MyRequest.postAsync = jest.fn(() => {
    throw 'error';
  });

  let expectedActions = [
    {type: UPDATE_IN_PROGRESS},
    {type: USER_SIGNED_OUT},
    {type: UPDATE_COMPLETE}
  ];

  await store.dispatch(userActions.loginUser('foo', 'bar'));
  expect(store.getActions()).toEqual(expectedActions);
});

Is there a way to trigger the catch block to execute in my test via a jest mock function (or any other way for that matter)? Would be annoying to not be able to test a large chunk of code (as all my requests work in the same way).

Thanks in advance for help with this.

like image 423
Andy Law Avatar asked Feb 24 '17 13:02

Andy Law


2 Answers

I don't know if it's still relevant, but you can do it in this way:

it('tests error with async/await', async () => {
  expect.assertions(1);
  try {
    await store.dispatch(userActions.loginUser('foo', 'bar'));
  } catch (e) {
    expect(e).toEqual({
      error: 'error',
    });
  }
});

Here is a documentation about error handling

like image 146
Yevhenii Herasymchuk Avatar answered Oct 17 '22 15:10

Yevhenii Herasymchuk


I had the same issue. For me the below works. Wrapping up the await with a try/catch

  it('calls expected actions when failed log in', async() => {
  MyRequest.postAsync = jest.fn(() => {
    throw 'error';
  });

  let expectedActions = [
    {type: UPDATE_IN_PROGRESS},
    {type: USER_SIGNED_OUT},
    {type: UPDATE_COMPLETE}
  ];
  try {
     await store.dispatch(userActions.loginUser('foo', 'bar'));
  } catch(e) {
     expect(store.getActions()).toEqual(expectedActions);
  }

});
like image 2
rajbharath Avatar answered Oct 17 '22 17:10

rajbharath