React Router v6.14.2本地正常,Jest测试报useLoaderData路由错误
解决Jest测试中useLoaderData报错"must be used within a data router"的问题
问题根源很明确:useLoaderData 是React Router数据路由(Data Router)专属的Hook,必须在由createBrowserRouter、createMemoryRouter这类API创建的路由上下文环境中使用。单独用Jest渲染ProfileList组件时,没有这个上下文,自然会报错。
方案1:用createMemoryRouter + RouterProvider模拟数据路由环境
这是最贴近真实运行环境的测试方式,步骤如下:
- 导入
createMemoryRouter和RouterProvider - 构建包含
ProfileList组件的路由配置,同时指定对应的loader(可以返回测试用的假数据) - 通过
RouterProvider渲染路由,再测试组件
示例代码:
import { render, screen, waitFor } from '@testing-library/react'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import ProfileList from './ProfileList'; // 模拟loader返回测试数据 const mockProfileLoader = () => { return [{ id: 1, name: 'Test User' }, { id: 2, name: 'Another User' }]; }; test('renders ProfileList with loader data', async () => { // 创建内存路由 const router = createMemoryRouter([ { path: '/profiles', element: <ProfileList />, loader: mockProfileLoader, }, ], { initialEntries: ['/profiles'], // 指定初始路由路径 }); // 渲染路由提供器 render(<RouterProvider router={router} />); // 等待loader数据加载完成,再校验元素 await waitFor(() => { expect(screen.getByText('Test User')).toBeInTheDocument(); }); });
方案2:Mock useLoaderData Hook(快速但不推荐)
如果只是想快速测试组件的UI渲染逻辑,不想搭建路由环境,可以直接mock这个Hook:
import { render, screen } from '@testing-library/react'; import { useLoaderData } from 'react-router-dom'; import ProfileList from './ProfileList'; // Mock useLoaderData返回测试数据 jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useLoaderData: jest.fn(), })); test('renders ProfileList with mocked loader data', () => { useLoaderData.mockReturnValue([{ id: 1, name: 'Mocked User' }]); render(<ProfileList />); expect(screen.getByText('Mocked User')).toBeInTheDocument(); });
注意:这种方式跳过了路由loader的真实执行逻辑,适合纯UI组件测试,但如果你的组件逻辑和loader强关联,还是推荐方案1。
内容的提问来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

