You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:22:10