React集成测试中认证接口Mock的401错误处理问题
解决方案
一、Mock真实流程还是直接返回200?
集成测试的核心是验证组件不同认证状态下的行为逻辑,而非真实调用后端接口,优先选Mock响应:
- 测试已认证状态:Mock
/auth/re和/auth/refresh-token返回200,验证组件是否渲染登录后内容; - 测试未认证状态:Mock返回401,验证组件是否触发登出、跳转登录页或显示未授权提示;
- 真实认证流程依赖cookie、后端服务,属于E2E测试范畴,集成测试没必要引入外部依赖,保持测试独立稳定。
二、解决Mock 401时Axios未处理错误的问题
问题出在AuthContext或Axios拦截器未正确处理401错误,导致测试抛出未捕获异常,两种解决方式:
方式1:Mock Axios并拦截错误
用jest.mock覆盖Axios,确保错误被处理,同时等待UI更新:
// 测试文件顶部Mock Axios jest.mock('axios', () => ({ create: () => ({ interceptors: { request: { use: jest.fn(), eject: jest.fn() }, response: { use: jest.fn((success) => success), jest.fn() } }, get: jest.fn((url) => { if (url.includes('/auth/re') || url.includes('/auth/refresh-token')) { return Promise.reject({ response: { status: 401 } }); } return Promise.resolve({}); }) }) })); test('未认证状态下显示登录提示', async () => { render(<AuthContextProvider>{/* 你的组件 */}</AuthContextProvider>); // 等待AuthContext处理401后的UI更新 await waitFor(() => { expect(screen.getByText('请登录')).toBeInTheDocument(); }); });
方式2:在测试中确保错误拦截器生效
如果你的401处理逻辑写在Axios响应拦截器里,测试前确保拦截器正确注册:
beforeEach(() => { const axiosInstance = require('axios').create(); // 手动注册错误拦截器,模拟实际业务逻辑 axiosInstance.interceptors.response.use( (res) => res, (err) => { if (err.response?.status === 401) { // 执行你的登出逻辑,比如更新AuthContext状态 AuthContext.dispatch({ type: 'LOGOUT' }); } return Promise.reject(err); } ); });
额外技巧:直接Mock AuthContext状态
如果只关注组件渲染逻辑,可跳过接口调用,直接模拟认证状态:
test('直接模拟已认证状态', () => { render( <AuthContext.Provider value={{ user: { id: 1, name: 'test' }, isAuthenticated: true }}> {/* 你的组件 */} </AuthContext.Provider> ); expect(screen.getByText('欢迎回来')).toBeInTheDocument(); });
内容的提问来源于stack exchange,提问作者W01v3n
相关产品推荐
相关产品推荐

