使用Vitest+Testing Library测试Login页面useNavigate重定向失败
可能原因及对应解决方案
1. 未等待异步登录操作完成
如果fakeAuth.login是异步函数,测试中点击按钮后直接断言会导致navigate还未被调用或参数未正确传递。
解决方法:使用waitFor等待异步操作完成:
import { waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; // 测试代码片段 const user = userEvent.setup(); const loginButton = screen.getByRole('button', { name: /login/i }); await user.click(loginButton); // 等待navigate调用完成后再断言 await waitFor(() => { expect(useNavigate).toHaveBeenCalledWith('/translation'); });
2. useNavigate的mock方式不正确
若mock时未正确返回可追踪的函数,或mock时机错误,会导致参数断言失败。
正确mock方式:
import { useNavigate } from 'react-router-dom'; import { vi } from 'vitest'; // 顶部mock整个react-router-dom模块,保留其他原有导出 vi.mock('react-router-dom', () => ({ ...vi.importActual('react-router-dom'), useNavigate: vi.fn(), })); // 类型安全地获取mock函数 const mockNavigate = vi.mocked(useNavigate); // 断言时使用mockNavigate await waitFor(() => { expect(mockNavigate).toHaveBeenCalledWith('/translation'); });
3. 组件中navigate路径被额外逻辑修改
检查Login组件中navigate的调用是否存在条件判断、路由前缀(如basename)等逻辑,导致实际调用路径并非/translation。
排查方法:在测试中打印mock的调用记录,确认实际参数:
// 测试中添加打印 console.log(mockNavigate.mock.calls);
根据打印结果调整断言的路径参数。
4. Mock未在测试前重置
多个测试共享mock时,未清除之前的调用记录会干扰当前测试。
解决方法:在beforeEach中重置mock:
beforeEach(() => { vi.clearAllMocks(); });
内容的提问来源于stack exchange,提问作者Aw3same
相关产品推荐
相关产品推荐

