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

Next.js 13中usePathname钩子组件测试报错求助

问题分析与解决方案

你遇到的报错核心原因有两点:

  1. jest.mock的提升机制:jest.mock会被自动提升到文件代码执行的最顶部,你在它之后定义的mockUsePathname变量,在jest.mock执行时还未初始化,此时值为undefined,导致模拟的usePathname函数返回undefined,触发类型错误。
  2. 错误的mock逻辑:你让模拟的usePathname返回mockUsePathname这个jest函数实例,而非让usePathname本身成为mock函数并返回路径字符串。组件调用usePathname()会得到一个函数,而非预期的路径字符串,既破坏组件逻辑也可能引发错误。

修正后的测试代码

import { expect, jest } from "@jest/globals";
import { cleanup, render, screen } from "@testing-library/react";
import { AuthContext } from "src/app/Context/AuthContext.tsx";
import * as mocks from "__mocks__/AuthContextMocks.ts";
import LoggedInPage from "./page.tsx";
import authContextPropsMock from "../../../../__mocks__/AuthContextMockFunc.ts";
import UserNavigationLayout from "./layout.tsx";
import { usePathname } from "next/navigation"; // 导入usePathname用于后续mock

// 正确模拟next/navigation模块
jest.mock("next/navigation", () => ({
  useRouter: () => ({
    push: jest.fn(),
    prefetch: jest.fn(),
  }),
  usePathname: jest.fn(), // 直接将usePathname设为jest mock函数
}));

describe("with usePathname", () => {
  // 重置mock避免测试用例污染
  beforeEach(() => {
    (usePathname as jest.Mock).mockReset();
  });

  it("should render the Logged In page when userRole is available in context", () => {
    // 指定当前路径的mock返回值
    (usePathname as jest.Mock).mockReturnValue("/dashboard");

    render(
      <AuthContext.Provider
        value={{
          ...authContextPropsMock,
          firstName: mocks.firstNameMock1,
          lastName: mocks.lastNameMock1,
        }}
      >
        <UserNavigationLayout>
          <LoggedInPage />
        </UserNavigationLayout>
      </AuthContext.Provider>,
    );
  
    expect(screen.getByText("Initial Dashboard")).toBeInTheDocument();
  });
});

可选优化:保留原模块其他导出

如果你需要保留next/navigation中未被模拟的其他导出(如useSearchParams),可以用jest.requireActual合并原模块内容:

jest.mock("next/navigation", () => ({
  ...jest.requireActual("next/navigation"), // 保留原模块未被mock的导出
  useRouter: () => ({
    push: jest.fn(),
    prefetch: jest.fn(),
  }),
  usePathname: jest.fn(),
}));

额外测试场景示例

如果需要测试路径匹配时的样式逻辑,只需修改mock返回值即可:

it("should apply active style when path matches link href", () => {
  (usePathname as jest.Mock).mockReturnValue("/dashboard");
  
  render(
    <DefaultLink href="/dashboard" name="Dashboard" styleBox="default" styleBoxOpen="active" />
  );

  expect(screen.getByText("Dashboard")).toHaveClass("active");
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:35:11