通过jest mock测试catch块

时间:2017-02-24 13:12:53

标签: unit-testing redux jestjs

我试图测试' catch'通过jest阻止异步redux动作,但在模拟中抛出一个catch导致整个测试失败。

我的行动如下:

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});
    }
  };
}

该测试试图模拟“MyRequest.postAsync”'抛出一个错误,从而触发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}
  ];

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

有没有办法通过jest模拟函数(或任何其他方式)触发catch块在我的测试中执行?如果不能测试大块代码(因为我的所有请求都以相同的方式工作)会很烦人。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我有同样的问题。对我来说,下面的工作。用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);
  }

});

答案 1 :(得分:1)

我不知道它是否仍然相关,但你可以这样做:

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',
    });
  }
});

以下是关于错误处理的documentation

答案 2 :(得分:0)

我将在测试功能中访问的实例变量设置为undefined,以便它可以捕获块。

PS:可能并非一直如此,因为我们可能一直都没有变量

class APIStore {

 async fetchProductsAPI() {
    try {
       const products =  networkManager.fetch('products')
       this.productsStore.setProducts(prodcuts)
    } 
    catch(e) {
       this.apiStatus = API_FAILED
       this.apiError = e
    }
  }
}

测试用例

it('Check API Error ', async () => {

    const toCheckErrorStore = new APIStore()

    // Setting products store to undefined so that execution goes to catch block
    toCheckErrorStore.productsStore = undefined

    await toCheckErrorStore.fetchProductsAPI()

    expect(toCheckErrorStore.apiStatus).toBe(API_FAILED)
    expect(toCheckErrorStore.apiError).toEqual(errorObjectIWantToCompareWith)
}