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

React测试中Jest模拟useNavigate函数失效问题求助

解决Jest模拟useNavigate无效的问题

你的测试失败核心原因是mock的模块不对:组件里从react-router-dom导入useNavigate,但测试里却mock了react-router模块,两者不匹配,导致组件实际调用的还是真实的useNavigate,而非你的模拟函数。

修正步骤:

  1. 修正mock的目标模块
    将jest.mock("react-router", ...)改为jest.mock("react-router-dom", ...),确保和组件的导入来源一致。

  2. 调整mock的结构
    react-router-dom的useNavigate是直接导出的成员,mock时要正确覆盖这个导出。

修正后的测试代码:

import userEvent from "@testing-library/user-event";
import { render, screen } from "../../utils/test.utils";
import Navbar from "../navbar";

const mockedUsedNavigate = jest.fn();

// 修正:mock react-router-dom 而非 react-router
jest.mock("react-router-dom", () => ({
  ...jest.requireActual("react-router-dom"),
  useNavigate: () => mockedUsedNavigate,
}));

describe("<Navbar />", () => {
  beforeEach(() => {
    mockedUsedNavigate.mockReset();
  });

  test("should navigate to the correct page", () => {
    render(<Navbar />);

    const accountButton = screen.getByText("Accounts", { exact: false });

    userEvent.click(accountButton);

    // 可额外断言调用参数是否正确
    expect(mockedUsedNavigate).toHaveBeenCalledTimes(1);
    expect(mockedUsedNavigate).toHaveBeenCalledWith("/accounts");
  });
});

额外检查点:

确认你的test.utils里的render函数,是否已经用MemoryRouter(或其他Router组件)包裹了被测试组件。如果没有,需要添加,否则useNavigate会抛出错误:

// 示例test.utils里的render实现
import { render as rtlRender } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";

export function render(ui, options = {}) {
  const Wrapper = ({ children }) => (
    <MemoryRouter>{children}</MemoryRouter>
  );
  return rtlRender(ui, { wrapper: Wrapper, ...options });
}

内容的提问来源于stack exchange,提问作者Cristian Rauber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:50:28