如何使用react-testing-library和jest mock自定义useAuth hook?
问题根因与解决方案
你的报错由两个核心问题导致,按优先级修复即可:
1. 修复jest.mock路径不匹配问题
你导入AuthProvider和组件内导入useAuth用的是别名路径helpers/auth,但jest.mock时用了相对路径../../../helpers/auth,如果jest没有正确配置别名路径映射,会导致你mock的模块和实际项目引用的不是同一个模块,useAuth未被正确mock,返回undefined。
修改mock代码为统一别名路径,同时补全useAuth返回的isLoggingIn字段,且因为组件内用await调用login,将login改为异步mock:
jest.mock('helpers/auth', () => ({ ...jest.requireActual('helpers/auth'), useAuth: jest.fn(() => ({ login: jest.fn().mockResolvedValue(true), isLoggingIn: false, })), }));
2. 移除测试中冗余的AuthProvider包裹
你已经直接mock了useAuth hook,它不会再读取AuthProvider的上下文值,外层包裹真实的AuthProvider反而可能和mock逻辑冲突,修改setup函数的render代码:
const setup = () => { const loginRender = render( <MemoryRouter> <ReactQueryProvider> <LoginForm /> </ReactQueryProvider> </MemoryRouter> ); // 原有逻辑保持不变 };
3. 修复测试用例的变量未定义问题
你在第二个、第三个测试用例中使用了form变量,但没有从setup返回值中解构,补充解构即可:
test('Inputs should accept email and password strings', async () => { const { emailField, passwordField, form } = setup(); // 原有逻辑保持不变 });
可选扩展用法
如果需要在不同测试用例模拟不同的登录状态(比如登录中、登录失败),可以单独覆盖useAuth的返回值:
// 测试登录失败场景 test('should show error when login failed', async () => { // 导入useAuth后重置mock返回值 (useAuth as jest.Mock).mockReturnValue({ login: jest.fn().mockRejectedValue(new Error('账号或密码错误')), isLoggingIn: false, }); const { getByTestId } = setup(); // 提交表单后校验错误提示展示逻辑 });
内容的提问来源于stack exchange,提问作者Atlante Avila
相关产品推荐
相关产品推荐

