NextJS 14 App目录route.js的Vitest测试失败,如何解决?
解决NextJS 14 App Router路由的Vitest测试问题
问题根源
你遇到的Request对象不存在.json()方法的错误,本质是两个原因:
- jsdom环境下的
Request实现和浏览器/NextJS运行时的标准实现存在差异,或是你创建的Request未正确传入可解析的请求体。 - 测试代码中创建的
Request未携带body,调用request.json()时触发异常,表现为类似"json()方法不存在"的错误。
修复方案
方案1:正确构造符合标准的Request对象
在测试中创建Request时,必须传入body并设置正确的Content-Type头,确保request.json()能正常解析:
import { describe, expect, it } from 'vitest' import { POST } from './route' describe('[POST] /api/test', () => { it('should respond with a `400` status code and error message', async () => { // 构造带body和正确头的Request const request = new Request('http://localhost:3000/api/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) // 根据路由逻辑传入对应测试数据 }) const res = await POST(request) const body = await res.json() expect(res.status).toBe(400) // 可额外断言错误消息 expect(body.error).toBeDefined() }) })
方案2:手动Mock Request的json方法
如果jsdom的Request仍有兼容性问题,直接mockjson()方法模拟请求体解析,避免依赖环境实现:
import { describe, expect, it, vi } from 'vitest' import { POST } from './route' describe('[POST] /api/test', () => { it('should respond with a `400` status code and error message', async () => { // Mock Request对象,模拟json()返回预设数据 const mockRequest = { json: vi.fn().mockResolvedValue({}) // 替换成你需要测试的请求数据 } as unknown as Request const res = await POST(mockRequest) const body = await res.json() expect(res.status).toBe(400) // 验证json()方法是否被调用(可选) expect(mockRequest.json).toHaveBeenCalled() }) })
额外检查:确保Vitest环境配置正确
确认你的vitest.config.js(或.ts)中已设置jsdom环境:
import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], test: { environment: 'jsdom', // 必须设置为jsdom globals: true // 可选,方便使用全局测试方法 } })
内容的提问来源于stack exchange,提问作者Michael Czolko
相关产品推荐
相关产品推荐

