如何使用Jest测试Next.js App Router的API路由?
Next.js App Router API路由测试问题解决
问题场景
你用Next.js App Router编写了一个简单的API路由(路径./src/app/api/name),代码如下:
import { NextResponse } from 'next/server'; export async function GET() { const name = process.env.NAME; return NextResponse.json({ name, }); }
测试时使用了如下代码:
import { GET } from './route'; describe('name', () => { it('should return url from environment variables', async () => { const result = await GET(); const { name } = await result.json(); expect(name).toEqual('test'); }); });
但运行测试时抛出错误:
FAIL src/app/api/name/route.spec.ts ● Test suite failed to run ReferenceError: Response is not defined 9 | } 10 | at Object.Response (node_modules/next/src/server/web/spec-extension/response.ts:29:51) at Object.<anonymous> (node_modules/next/dist/server/web/exports/next-response.js:12:19) at Object.<anonymous> (src/api/name/route.ts:11:62) at Object.<anonymous> (src/api/name/route.spec.ts:5:16)
之前参考的教程均基于Pages Router,不清楚App Router下该如何正确测试。
解决办法
1. 修复Response is not defined错误
这个错误源于Node.js测试环境缺少浏览器端的Response Web API,而Next.js的NextResponse依赖该对象。有两种常用解决方式:
方式一:手动注入Response对象
在测试文件顶部添加代码,引入node-fetch提供的Response:
global.Response = require('node-fetch').Response;
方式二:使用Next.js官方测试配置(推荐)
安装@next/jest自动配置测试环境:
npm install --save-dev @next/jest jest
在项目根目录创建jest.config.js:
const nextJest = require('@next/jest') const createJestConfig = nextJest({ dir: './', }) const customJestConfig = { moduleDirectories: ['node_modules', '<rootDir>/'], testEnvironment: 'jest-environment-jsdom', } module.exports = createJestConfig(customJestConfig)
配置完成后,测试环境会自动包含所需的Web API,无需手动注入。
2. 正确设置测试环境变量
测试时需要给process.env.NAME赋值,确保测试逻辑能拿到预期值。可以通过测试钩子函数在测试前后设置和清理:
beforeEach(() => { process.env.NAME = 'test'; }); afterEach(() => { delete process.env.NAME; });
3. 完整测试示例
结合上述配置,修改后的测试代码如下:
import { GET } from './route'; describe('name API路由', () => { beforeEach(() => { process.env.NAME = 'test'; }); afterEach(() => { delete process.env.NAME; }); it('应该返回环境变量中的name值', async () => { const result = await GET(); const { name } = await result.json(); expect(name).toEqual('test'); }); });
内容的提问来源于stack exchange,提问作者frtelg
相关产品推荐
相关产品推荐

