如何为React Router v6中调用useLoaderData()的组件编写自定义数据单元测试?
测试使用useLoaderData()的React组件(React Router v6)
针对你这种不想执行真实fetch、只想提供测试数据的场景,有两种实用的测试方式:
方法一:直接mock useLoaderData钩子
如果只是单独测试ListWidgets组件的渲染逻辑,不需要涉及路由跳转等场景,直接mock React Router的useLoaderData钩子就行,步骤如下:
- 在测试文件里mock
useLoaderData的返回值,用Jest的mock功能:
import { render, screen } from '@testing-library/react'; import { useLoaderData } from 'react-router-dom'; import ListWidgets from './ListWidgets'; // mock useLoaderData钩子,保留其他原方法 jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useLoaderData: jest.fn() })); test('渲染测试用的组件列表', () => { // 自定义测试数据 const mockWidgets = [ { id: 1, name: '测试组件1' }, { id: 2, name: '测试组件2' } ]; // 让useLoaderData返回我们的测试数据 useLoaderData.mockReturnValue(mockWidgets); render(<ListWidgets />); // 验证渲染结果 expect(screen.getByText(`Here is a list of ${mockWidgets.length} widgets:`)).toBeInTheDocument(); // 还可以继续验证每个组件项是否正确渲染 });
方法二:用React Router测试工具模拟路由环境
如果想更贴近真实的路由场景测试(比如验证loader逻辑和组件的联动),可以用MemoryRouter和Route组件搭建测试环境,传入自定义的测试loader:
import { render, screen } from '@testing-library/react'; import { MemoryRouter, Route, Routes } from 'react-router-dom'; import ListWidgets from './ListWidgets'; test('通过模拟路由渲染组件并传入测试数据', () => { const mockWidgets = [ { id: 1, name: '测试组件1' }, { id: 2, name: '测试组件2' } ]; // 自定义测试用的loader,直接返回测试数据 const testLoader = () => mockWidgets; render( <MemoryRouter initialEntries={['/widgets']}> <Routes> <Route path="/widgets" loader={testLoader} element={<ListWidgets />} /> </Routes> </MemoryRouter> ); expect(screen.getByText(`Here is a list of ${mockWidgets.length} widgets:`)).toBeInTheDocument(); });
两种方式的区别
- 方法一更轻量,适合单独测试组件的渲染逻辑,不需要关心路由上下文;
- 方法二更接近真实应用场景,能同时测试路由配置和组件的配合逻辑,适合需要验证loader数据流转的场景。
内容的提问来源于stack exchange,提问作者codeape
相关产品推荐
相关产品推荐

