如何在Next.js 14.1.0中用Vitest测试App Router路由?
在Next.js 14.1.0中用Vitest测试路由的实现思路
组件级路由测试(对应React Router组件测试场景)
Next.js的路由组件(page.tsx、layout.tsx等)本质是React组件,测试核心逻辑和普通组件一致:
- 测试组件渲染:直接用
@testing-library/react渲染组件,断言内容是否正确。 - 测试路由跳转:模拟Next.js的路由钩子(App Router用
next/navigation的useRouter,Pages Router用next/router的useRouter),验证跳转行为:import { useRouter } from 'next/navigation'; import { render, screen, fireEvent } from '@testing-library/react'; import HomePage from './page'; vi.mock('next/navigation', () => ({ useRouter: () => ({ push: vi.fn(), }), })); test('点击跳转按钮触发/about路由', () => { const router = useRouter(); render(<HomePage />); fireEvent.click(screen.getByRole('button', { name: '去关于页' })); expect(router.push).toHaveBeenCalledWith('/about'); });
集成级路由测试(模拟完整导航流程)
如果要测试从一个路由到另一个路由的完整流程,需要模拟Next.js的路由上下文:
- 借助
RouterContext包裹测试组件,手动管理路由状态并触发重新渲染:import { RouterContext } from 'next/dist/shared/lib/router-context'; import { render, screen, fireEvent } from '@testing-library/react'; import HomePage from './page'; import AboutPage from '../about/page'; test('从首页跳转后渲染关于页内容', async () => { let currentPath = '/'; const mockRouter = { push: (path: string) => { currentPath = path; }, pathname: currentPath, // 按需添加其他路由属性(如query、asPath) }; const { rerender } = render( <RouterContext.Provider value={mockRouter}> {currentPath === '/' ? <HomePage /> : <AboutPage />} </RouterContext.Provider> ); fireEvent.click(screen.getByText('去关于页')); rerender( <RouterContext.Provider value={mockRouter}> {currentPath === '/' ? <HomePage /> : <AboutPage />} </RouterContext.Provider> ); expect(screen.getByText('关于我们')).toBeInTheDocument(); }); - 嵌套路由测试:直接组合渲染
layout.tsx和对应的page.tsx,验证布局与页面的配合逻辑。
动态路由测试
对于/posts/[id]/page.tsx这类动态路由,模拟useParams钩子获取路由参数:
import { useParams } from 'next/navigation'; import { render, screen } from '@testing-library/react'; import PostPage from './page'; vi.mock('next/navigation', () => ({ useParams: () => ({ id: '123' }), })); test('动态路由页面正确显示ID', () => { render(<PostPage />); expect(screen.getByText('Post ID: 123')).toBeInTheDocument(); });
关键注意事项
- 配置Vitest:确保
vitest.config.ts中正确处理Next.js的模块解析(比如使用vite-plugin-next)。 - Server Components测试:如果是Server Components,需使用
next/test-utils提供的render函数,而非@testing-library/react的默认方法。 - 聚焦业务逻辑:无需测试Next.js原生路由的底层行为,只验证你的代码(如跳转触发、参数处理、组件渲染逻辑)。
内容的提问来源于stack exchange,提问作者Yuri
相关产品推荐
相关产品推荐

