Jest测试Redux异步Action时Catch块Dispatch未触发问题求助
Redux异步Action测试问题:Catch块dispatch未触发
我正在用Jest和Enzyme测试React+Redux课程项目,测试Redux Action时遇到了问题:
有一个requestRobots函数负责异步数据获取,基于Promise结果在then/catch逻辑中分发Action,由redux-thunk中间件处理。实际项目中出错时,Catch块能正常分发失败Action,但Jest测试时,错误虽被捕获并打印,Catch块内的dispatch却未触发。我用redux-mock-store搭建了Mock Redux Store,代码中的apiCall是fetch API的抽象封装。
相关代码
action.test.js
it("Test request robots action when called - unsuccessful state", async () => { const apiCall = jest.fn().mockReturnValue(Promise.reject("Not found")); const store = mockStore(); await store.dispatch(actions.requestRobots(apiCall)); const action = store.getActions(); console.log(action); expect(apiCall).toBeCalled(); expect(apiCall.mock.calls.length).toBeGreaterThan(0); console.log(apiCall.mock); });
action.js
export const requestRobots = apiCall => dispatch => { dispatch({ type: REQUEST_ROBOTS_PENDING }); apiCall("https://jsonplaceholder.typicode.com/users") .then(data => dispatch({ type: REQUEST_ROBOTS_SUCCESS, payload: data })) .catch(error => { console.log(error); dispatch({ type: REQUEST_ROBOTS_FAILED, payload: error }); }); };
测试输出日志(翻译后)
console.log: action: [ { type: 'REQUEST_ROBOTS_PENDING' } ] console.log: Not found 测试通过,但未捕获到REQUEST_ROBOTS_FAILED类型的Action
问题原因及解决方案
问题根源在于requestRobots没有返回Promise链,导致测试中的await无法等待异步操作完成。当执行await store.dispatch(actions.requestRobots(apiCall))时,dispatch会立即返回,此时Catch块里的dispatch还未执行,所以store.getActions()只能拿到REQUEST_ROBOTS_PENDING这一个Action。
修复步骤:
- 修改
requestRobots,让它返回apiCall的Promise链:
export const requestRobots = apiCall => dispatch => { dispatch({ type: REQUEST_ROBOTS_PENDING }); // 返回Promise,让await能等待异步流程结束 return apiCall("https://jsonplaceholder.typicode.com/users") .then(data => dispatch({ type: REQUEST_ROBOTS_SUCCESS, payload: data })) .catch(error => { console.log(error); dispatch({ type: REQUEST_ROBOTS_FAILED, payload: error }); }); };
- 完善测试断言,验证失败Action是否被正确分发:
it("Test request robots action when called - unsuccessful state", async () => { const apiCall = jest.fn().mockReturnValue(Promise.reject("Not found")); const store = mockStore(); await store.dispatch(actions.requestRobots(apiCall)); const actions = store.getActions(); expect(apiCall).toHaveBeenCalled(); expect(actions).toEqual([ { type: 'REQUEST_ROBOTS_PENDING' }, { type: 'REQUEST_ROBOTS_FAILED', payload: 'Not found' } ]); });
内容的提问来源于stack exchange,提问作者sridarshan
相关产品推荐
相关产品推荐

