You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:40:23