在Vitest中mock react-router-dom的useParams返回{}而非预期值
解决Vitest中mock useParams返回空对象的问题
你遇到的问题是mock useParams后组件拿到空对象,下面提供两种可行的解决方式:
方式一:调整mock的设置时机
原来的模块级mock可能因为初始化时机问题导致返回值未生效,可以将mock返回值的设置移到测试用例内部:
import { render } from '@testing-library/react'; import { describe, it, vi, expect } from 'vitest'; import { useParams } from 'react-router-dom'; import MyComponent from './Component'; // 先初始化mock函数,不预设返回值 vi.mock('react-router-dom', () => ({ ...vi.importActual('react-router-dom'), useParams: vi.fn(), })); describe('MyComponent', () => { it('should use mocked useParams', () => { // 在测试用例中明确设置mock返回值 useParams.mockReturnValue({ id: '123' }); render(<MyComponent />); // 可添加断言验证mock生效 expect(useParams).toHaveBeenCalled(); // 如果组件渲染了id相关内容,可进一步断言 // expect(screen.getByText('123')).toBeInTheDocument(); }); });
方式二:使用MemoryRouter模拟真实路由(更推荐)
直接mock钩子容易出现上下文相关问题,更可靠的方式是用MemoryRouter模拟真实路由环境,无需mock useParams:
import { render, screen } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; import { MemoryRouter } from 'react-router-dom'; import MyComponent from './Component'; describe('MyComponent', () => { it('should get correct id from route params', () => { // 模拟路由路径,假设你的组件对应/items/:id路径 render( <MemoryRouter initialEntries={['/items/123']}> <MyComponent /> </MemoryRouter> ); // 验证组件正确获取到id // 示例:如果组件渲染了`Item ID: 123`,则断言 // expect(screen.getByText('Item ID: 123')).toBeInTheDocument(); }); });
这种方式更贴近真实用户场景,避免了mock钩子带来的潜在问题,测试结果也更可信。
内容的提问来源于stack exchange,提问作者Hubert Kuzdak
相关产品推荐
相关产品推荐

