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

使用Vitest+Testing Library测试Login页面useNavigate重定向失败

解决Vitest测试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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:16:04