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

为何Next.js Router的Mock未生效?测试出现No router instance found错误

问题原因及解决方案

可能的原因

1. 模块导入顺序错误

如果测试文件中先导入了目标组件(如SignIn),再执行mock操作,由于Node.js的模块缓存机制,AuthContext.js在mock生效前就已经加载了原始的next/router模块,导致mock无法覆盖原有逻辑。

2. mock方式或匹配对象不对

仅用jest.spyOn可能无法覆盖组件已加载的useRouter实例,尤其是组件导入早于mock执行时。另外,若AuthContext中直接引用了next/router的Router全局实例(而非useRouter钩子),那么mockuseRouter完全无效——错误提示明确指向Router.pathname,说明代码中是直接访问全局Router对象,而非钩子返回的router实例。

对应的解决方案

方案1:调整顺序,确保mock先执行

在测试文件中,先完成next/router的mock,再导入需要测试的组件:

// 先mock useRouter
const useRouter = jest.spyOn(require('next/router'), 'useRouter');
useRouter.mockImplementation(() => ({ pathname: '/' }));

// 再导入测试组件
import SignIn from '../components/SignIn';

方案2:用jest.mock直接mock整个模块(更可靠)

相比jest.spyOn,直接mock整个next/router模块能彻底避免导入顺序问题:

jest.mock('next/router', () => ({
  useRouter: () => ({
    pathname: '/'
  })
}));

// 后续导入组件
import SignIn from '../components/SignIn';

方案3:若直接使用Router全局实例,需额外mock

如果AuthContext.js中的代码是直接引用全局Router:

import Router from 'next/router';

useEffect(() => {
  const currentPath = Router.pathname;
  // ...其他逻辑
}, []);

则需要同时mockRouter对象:

jest.mock('next/router', () => ({
  useRouter: () => ({ pathname: '/' }),
  Router: {
    pathname: '/'
  }
}));

额外建议

优先使用useRouter钩子而非直接引用Router全局实例,Next.js官方推荐在客户端组件中使用useRouter,直接使用全局Router在服务端或测试环境更容易出现实例不存在的问题。

内容的提问来源于stack exchange,提问作者A.B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:25:00