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

升级NextJS v12.2.0后JEST测试出现Router空引用问题

NextJS v12.2.x升级后面包屑组件测试路由问题

问题描述

将NextJS从v12.1.6升级至v12.2.2后,仅BreadcrumbTrail组件的测试套件出现路由问题:点击面包屑时抛出「TypeError: Cannot read property 'push' of null」错误,推测asPath未更新的次级问题由该空引用引发。

基础技术栈

  • React v18.2.0
  • Next v12.2.0
  • JEST v28.1.1

已调研情况

v12.2.0版本前测试可正常通过,发现NextJS的PR 36660修复了asPath竞态条件问题,但该修复可能导致当前故障。

测试代码

import { render, screen, within, waitFor } from "@testing-library/react";
import singletonRouter from "next/router";
import mockRouter from "next-router-mock";
import userEvent from "@testing-library/user-event";
import { BreadcrumbTrail } from "./BreadcrumbTrail";

jest.mock("next/dist/client/router", () => require("next-router-mock"));

const navPath = "/some-navpath";

describe("BreadcrumbTrail", function () {
  beforeEach(() => {
    mockRouter.setCurrentUrl(navPath);
  });

  it("navigates to the correct location when clicking on a crumb", async function () {
    render(<BreadcrumbTrail />);
    const breadcrumbs = screen.getByRole("list", { name: /breadcrumbs/i });
    const { getByText } = within(breadcrumbs);
    const breadcrumb = getByText("Foo");

    await userEvent.click(breadcrumb);

    await waitFor(() =>
      expect(singletonRouter).toMatchObject({
        asPath: "/someother-navpath",
      }),
    );
  });
});

错误信息

错误一:push方法空引用

FAIL  components/Navigation/BreadcrumbTrail.test.tsx

Console

 console.error
   Error: Uncaught [TypeError: Cannot read property 'push' of null]

...
...
...

EventTarget.js:241:34)
   at dispatchEvent (/<Repository Path>/node_modules/@testing-library/user-event/dist/index.cjs:1716:33)
   at /<Repository Path>/node_modules/@testing-library/react/dist/pure.js:125:16
   at /<Repository Path>/node_modules/@testing-library/react/dist/act-compat.js:110:24
   at act (/<Repository Path>/node_modules/react/cjs/react.development.js:2457:20) {
     detail: TypeError: Cannot read property 'push' of null
        at navigate (/<Repository Path>/node_modules/next/dist/client/link.js:90:11)
        at linkClicked (/<Repository Path>/node_modules/next/dist/client/link.js:100:5)
        at onClick (/<Repository Path>/node_modules/next/dist/client/link.js:330:9)
        at HTMLUnknownElement.callCallback (/<Repository Path>/node_modules/react-dom/cjs/react-dom.development.js:730:119)

...
...
...

BreadcrumbTrail › navigates to the correct location when clicking on a crumb

    TypeError: Cannot read property 'push' of null

      40 |     const breadcrumb = getByText("Foo");
      41 |
    > 42 |     await userEvent.click(breadcrumb);

错误二:asPath未更新

expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 1

Object {
-   "asPath": "/someother-navpath",
+   "asPath": "/some-navpath",
}

疑问

  1. 是否有人遇到NextJS v12.2.0的路由错误?
  2. 有无解决该问题的建议?

解决方案建议

  1. 升级next-router-mock适配新版本
    NextJS v12.2.x对路由内部逻辑做了调整,旧版本的next-router-mock可能未兼容新的路由实例结构,导致push方法引用为空。升级next-router-mock到最新兼容版本,确保其能正确模拟NextJS v12.2.x的路由行为。

  2. 手动完善mock路由的push方法
    如果升级mock库后问题仍存在,可手动扩展mockRouter的push方法,确保其正确更新路由状态:

beforeEach(() => {
  mockRouter.setCurrentUrl(navPath);
  // 重写push方法,确保调用时更新asPath
  mockRouter.push = jest.fn((url) => {
    mockRouter.setCurrentUrl(url);
    return Promise.resolve();
  });
});
  1. 检查组件内路由调用逻辑
    验证BreadcrumbTrail组件中使用next/link或useRouter的方式是否符合NextJS v12.2.x的要求。新版本的Link组件可能对路由实例的获取方式有变化,确保组件通过useRouter钩子获取路由实例,而非直接依赖全局路由对象。

  2. 临时禁用PR 36660的修复
    如果确认是PR 36660的修复导致问题,可通过NextJS配置临时禁用该特性:

// next.config.js
module.exports = {
  experimental: {
    fixAsPathRaceCondition: false
  }
};

该方案仅作临时 workaround,后续需跟进适配官方修复。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:57:58