升级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", }
疑问
- 是否有人遇到NextJS v12.2.0的路由错误?
- 有无解决该问题的建议?
解决方案建议
升级
next-router-mock适配新版本
NextJS v12.2.x对路由内部逻辑做了调整,旧版本的next-router-mock可能未兼容新的路由实例结构,导致push方法引用为空。升级next-router-mock到最新兼容版本,确保其能正确模拟NextJS v12.2.x的路由行为。手动完善mock路由的push方法
如果升级mock库后问题仍存在,可手动扩展mockRouter的push方法,确保其正确更新路由状态:
beforeEach(() => { mockRouter.setCurrentUrl(navPath); // 重写push方法,确保调用时更新asPath mockRouter.push = jest.fn((url) => { mockRouter.setCurrentUrl(url); return Promise.resolve(); }); });
检查组件内路由调用逻辑
验证BreadcrumbTrail组件中使用next/link或useRouter的方式是否符合NextJS v12.2.x的要求。新版本的Link组件可能对路由实例的获取方式有变化,确保组件通过useRouter钩子获取路由实例,而非直接依赖全局路由对象。临时禁用PR 36660的修复
如果确认是PR 36660的修复导致问题,可通过NextJS配置临时禁用该特性:
// next.config.js module.exports = { experimental: { fixAsPathRaceCondition: false } };
该方案仅作临时 workaround,后续需跟进适配官方修复。
内容的提问来源于stack exchange,提问作者Damian
相关产品推荐
相关产品推荐

