React Router Dom v6中usePrompt调用参数测试断言失败如何解决?
解决React Router usePrompt测试断言失败的问题
问题分析
你的测试断言失败通常有几个常见原因:mock方式不正确、未等待React渲染完成、或者对象参数的匹配方式不对(因为对象是引用类型,严格相等会失败)。下面是具体的修复步骤:
1. 正确Mock unstable_usePrompt
确保你完整mock了react-router-dom的导出,同时保留其他真实的API(比如createMemoryRouter、RouterProvider),避免破坏路由上下文:
// Prompt.test.js import React from 'react'; import { render, waitFor } from '@testing-library/react'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import Prompt from './Prompt'; // 只mock unstable_usePrompt,保留其他真实导出 jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), unstable_usePrompt: jest.fn(), })); // 提取mock的方法 const mockedUsePrompt = jest.requireMock('react-router-dom').unstable_usePrompt;
2. 确保组件在路由上下文内正确渲染
用createMemoryRouter配置包含Prompt组件的路由,确保组件被挂载到路由树中:
describe('Prompt Component', () => { beforeEach(() => { // 每次测试前重置mock调用记录 mockedUsePrompt.mockClear(); }); it('calls usePrompt with correct parameters', async () => { const router = createMemoryRouter([ { path: '/', element: <Prompt when={true} message="Are you sure?" />, }, ]); render(<RouterProvider router={router} />); // 等待React完成渲染,确保mock方法被调用 await waitFor(() => { // 使用expect.objectContaining匹配对象属性,忽略引用差异 expect(mockedUsePrompt).toHaveBeenCalledWith( expect.objectContaining({ when: true, message: 'Are you sure?' }) ); }); }); });
3. 关键注意点
- 对象参数匹配:不要直接用字面量对象断言,因为
usePrompt接收的对象和你断言的对象是不同引用,用expect.objectContaining可以只检查属性值是否匹配。 - 异步等待:React组件渲染是异步的,必须用
waitFor或act包裹断言,确保mock方法已经被调用。 - 重置mock:在每个测试前用
mockClear()重置mock的调用记录,避免测试之间的状态污染。
内容的提问来源于stack exchange,提问作者Alexei Delezhov
相关产品推荐
相关产品推荐

