使用Moxios与Jest测试Axios请求时catch块未触发问题排查
如何让axios请求失败场景触发测试中的catch块?
我来帮你捋清楚问题的核心,以及对应的解决办法:
问题根源:你的Promise永远不会被Reject
看一下你的genericTryCatch函数——它在内部捕获了axios请求抛出的错误,然后返回了ApiError.errorHandler(error)的结果。这就意味着,不管axios请求成功还是失败,getRaw方法返回的Promise都会处于resolved状态,而不是rejected状态。
所以你测试里写的.then(mockFunction)会被执行,但永远不会进入catch分支,因为根本没有rejection可以捕获。
解决方案1:不修改业务代码,测试错误处理后的结果
如果不想改动现有业务逻辑,你需要调整测试思路:既然getRaw会把错误处理后的结果作为resolved值返回,那我们就去断言这个返回值,同时验证errorHandler被正确调用。
修改后的测试代码如下:
it('should call errorHandler method when request is rejected', done => { // 注意:errorHandler里取的是error.response.data,所以要把错误响应的结构补全 const errorResp = { status: 400, response: { data: 'invalid data' } }; // 先mock errorHandler方法,方便断言调用情况 const mockErrorHandler = jest.spyOn(ApiError, 'errorHandler').mockReturnValue('handled error message'); Axios.getRaw('/test').then(result => { // 断言errorHandler被传入了正确的错误对象 expect(mockErrorHandler).toHaveBeenCalledWith(expect.objectContaining(errorResp)); // 断言返回的是errorHandler处理后的结果 expect(result).toBe('handled error message'); done(); }); moxios.wait(() => { const req = moxios.requests.mostRecent(); req.reject(errorResp); }); });
解决方案2:修改业务代码,让错误能向外传递
如果你希望getRaw在处理错误后仍然向外抛出错误(这样外层的catch能触发),可以调整genericTryCatch函数,在处理完错误后把它抛出,而不是返回:
// 修改后的API_WRAPPER.genericTryCatch genericTryCatch: async (executionMethod) => { try { const response = await executionMethod; return response; } catch (error) { const handledError = ApiError.errorHandler(error); // 把处理后的错误抛出,让外层Promise变成rejected状态 throw handledError; } }
此时测试代码就可以按你原本的思路,捕获rejection并断言:
it('should call errorHandler method when request is rejected', done => { const errorResp = { status: 400, response: { data: 'invalid data' } }; const mockErrorHandler = jest.spyOn(ApiError, 'errorHandler').mockReturnValue('handled error message'); Axios.getRaw('/test') .then(() => { // 如果进入这里,说明测试失败(因为预期请求会被reject) done(new Error('Expected request to reject but it resolved')); }) .catch(error => { expect(mockErrorHandler).toHaveBeenCalledWith(expect.objectContaining(errorResp)); expect(error).toBe('handled error message'); done(); }); moxios.wait(() => { const req = moxios.requests.mostRecent(); req.reject(errorResp); }); });
额外注意点
你原来的errorResp结构里写的是response: {message: 'invalid data'},但errorHandler里取的是error.response.data,所以要确保错误响应的结构和errorHandler的预期匹配,否则会出现Cannot read properties of undefined (reading 'data')的错误。
内容的提问来源于stack exchange,提问作者Sabu Shakya
相关产品推荐
相关产品推荐

