Next.js 集成 Jest 测试时出现 TypeError:'original' 参数必须为函数,却接收到 Object 实例
我之前也碰到过类似的诡异报错,结合你排查出来的「只要导入组件就报错,哪怕测试里根本不用它」这个关键点,大概率是 Next.js 和 Jest 的配置冲突,或者相关 Babel 插件不兼容导致的。给你几个具体的排查和解决方向:
1. 改用 Next.js 官方的 Jest 配置工具
Next.js 官方提供了 @next/jest 包,专门用来处理 Next.js 和 Jest 的兼容性问题,很多配置冲突用它就能解决。
步骤如下:
- 安装依赖:
npm install --save-dev @next/jest jest-environment-jsdom
- 在项目根目录创建
jest.config.js,配置内容如下:
const nextJest = require('next/jest') const createJestConfig = nextJest({ // 指定你的 Next.js 项目根目录 dir: './', }) const customJestConfig = { // 配置测试环境为 jsdom(React Testing Library 需要这个) testEnvironment: 'jest-environment-jsdom', moduleDirectories: ['node_modules', '<rootDir>/'], } module.exports = createJestConfig(customJestConfig)
之后重新运行测试,看看报错是否消失。
2. 排查 Babel 覆盖率插件的冲突
错误栈里提到了 babel-plugin-istanbul,这个插件是用来生成测试覆盖率报告的。如果你在 Jest 配置里开启了覆盖率收集(比如 collectCoverage: true),或者手动在 Babel 配置里加了这个插件,很可能和 Next.js 的内置 require hook 冲突。
可以先临时关闭覆盖率收集:在 jest.config.js 里把 collectCoverage 设为 false,然后重新运行测试。如果报错消失了,说明就是这个插件的问题。
解决办法:
- 升级
@next/jest和babel-plugin-istanbul到最新版本,看看兼容性是否修复; - 改用 Next.js 官方支持的方式收集覆盖率,避免手动配置
babel-plugin-istanbul。
3. 修正组件的参数写法 + 检查服务器组件问题
先提个小问题:你的组件写法有个小错误——React 组件接收的是props 对象,不是单个参数,应该改成解构的形式:
// 修正前 export default function Thumbnail(src){ ... } // 修正后 export default function Thumbnail({ src }){ return <img src={src} />; };
另外,如果你的组件放在 Next.js 13+ 的 src/app/ 目录下,它默认是服务器组件,而服务器组件无法在客户端测试环境中直接渲染。可以在组件顶部加上 'use client' 指令,把它标记为客户端组件:
'use client' export default function Thumbnail({ src }){ return <img src={src} />; };
4. 清理依赖缓存
有时候依赖缓存会导致各种奇怪的兼容性问题,可以尝试清空缓存后重新安装依赖:
# 删除 node_modules 和锁文件 rm -rf node_modules package-lock.json # 清理 npm 缓存 npm cache clean --force # 重新安装依赖 npm install
按照上面的步骤一步步排查,应该能解决这个报错。如果还是不行,可以检查一下你的 Next.js 版本和 Jest 版本是否匹配,比如 Next.js 13+ 建议使用 Jest 29.x 版本。
内容来源于stack exchange

