React测试中Jest模拟useNavigate函数失效问题求助
你的测试失败核心原因是mock的模块不对:组件里从react-router-dom导入useNavigate,但测试里却mock了react-router模块,两者不匹配,导致组件实际调用的还是真实的useNavigate,而非你的模拟函数。
修正步骤:
修正mock的目标模块
将jest.mock("react-router", ...)改为jest.mock("react-router-dom", ...),确保和组件的导入来源一致。调整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
相关产品推荐
相关产品推荐

