NextJS App Router异步组件测试报错:fetch未定义及渲染问题
解决Next.js App Router异步页面测试的两个问题
1. 修复ReferenceError: fetch is not defined
Jest运行在Node.js环境中,Node.js v18之前默认没有内置fetchAPI,解决方式分两种:
方式一:用Next.js官方Jest预设
Next.js的next/jest预设已经内置了fetch的polyfill,确保你的Jest配置正确:
在项目根目录的jest.config.js中添加:
const nextJest = require('next/jest') const createJestConfig = nextJest({ dir: './', // 你的Next.js项目根目录 }) const customJestConfig = { setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], testEnvironment: 'jest-environment-jsdom', } module.exports = createJestConfig(customJestConfig)
方式二:手动添加polyfill
如果不想依赖官方预设,可自行安装并导入:
- 安装依赖:
npm install whatwg-fetch --save-dev - 在
jest.setup.js中导入:import 'whatwg-fetch';
2. 正确测试异步页面组件
App Router的页面组件是异步函数(返回Promise),直接render(<UsersPage />)会报错,因为React无法渲染Promise对象。需要用Suspense组件包裹,并通过异步查询等待数据加载完成。
测试示例(mock fetch)
假设你的app/users/page.js代码如下:
async function getUsers() { const res = await fetch('https://api.example.com/users'); return res.json(); } export default async function UsersPage() { const users = await getUsers(); return ( <div> <h1>Users</h1> <ul>{users.map(user => <li key={user.id}>{user.name}</li>)}</ul> </div> ); }
对应的测试代码:
import { render, screen, waitFor } from '@testing-library/react'; import UsersPage from '../app/users/page'; import { Suspense } from 'react'; // Mock全局fetch global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve([{ id: 1, name: 'Test User' }]), }) ); describe('/users 页面测试', () => { // 测试后清除mock afterEach(() => jest.clearAllMocks()); it('获取并渲染用户列表', async () => { // 用Suspense包裹异步页面,添加加载占位 render( <Suspense fallback={<div>加载中...</div>}> <UsersPage /> </Suspense> ); // 验证fetch是否被正确调用 await waitFor(() => { expect(fetch).toHaveBeenCalledWith('https://api.example.com/users'); }); // 等待用户列表渲染完成并验证 const userItem = await screen.findByText('Test User'); expect(userItem).toBeInTheDocument(); }); });
关键要点
- 必须用
Suspense包裹异步页面组件,模拟Next.js渲染Server Component的行为 - 使用
screen.findBy*(异步查询)或waitFor等待数据加载完成,避免过早断言 - 直接mock全局
fetch即可,无需单独mock页面内部的getUsers函数,更贴近真实场景
内容的提问来源于stack exchange,提问作者medev21
相关产品推荐
相关产品推荐

