React组件测试:Mock useParams()报“Cannot spyOn on a primitive value; undefined given”
解决React测试中Mock useParams()报错的问题
错误原因分析
这个报错是因为你尝试spyOn的目标不是一个可被监听的函数对象,大概率是mock react-router-dom的方式有误,导致useParams被处理成了undefined或者非函数类型。
可行解决方案
方案1:直接Mock useParams返回指定参数值
在测试文件中直接覆盖react-router-dom的useParams方法,让它返回你需要的URL参数:
// Item.test.js import React from 'react'; import { render, screen } from '@testing-library/react'; import Item from './Item'; import { useParams } from 'react-router-dom'; // 保留原模块其他方法,仅mock useParams jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useParams: jest.fn(() => ({ id: 'test-id-123' })) })); describe('Item组件测试', () => { it('能正确获取并渲染URL参数id', () => { render(<Item />); // 根据你的组件逻辑编写断言,比如检查是否渲染了对应id的内容 expect(screen.getByText(/test-id-123/i)).toBeInTheDocument(); }); });
方案2:动态修改Mock返回值(多测试用例场景)
如果需要在不同测试用例中返回不同的id,可以先mock模块,再用spyOn动态调整返回值:
// Item.test.js import React from 'react'; import { render, screen } from '@testing-library/react'; import Item from './Item'; import * as reactRouterDom from 'react-router-dom'; describe('Item组件测试', () => { it('渲染id为123的内容', () => { const useParamsSpy = jest.spyOn(reactRouterDom, 'useParams') .mockReturnValue({ id: '123' }); render(<Item />); expect(screen.getByText(/123/i)).toBeInTheDocument(); // 清理mock,避免影响其他用例 useParamsSpy.mockRestore(); }); it('渲染id为456的内容', () => { const useParamsSpy = jest.spyOn(reactRouterDom, 'useParams') .mockReturnValue({ id: '456' }); render(<Item />); expect(screen.getByText(/456/i)).toBeInTheDocument(); useParamsSpy.mockRestore(); }); });
常见错误排查点
- 检查
Item.js中是否正确导入了useParams:
// Item.js import { useParams } from 'react-router-dom'; export default function Item() { const { id } = useParams(); return <div>当前Item ID:{id}</div>; }
- 避免同时使用
jest.mock和spyOn时出现冲突,确保mock的目标始终是函数类型 - 不要将
useParams误设为undefined或原始值(如字符串、数字)
内容的提问来源于stack exchange,提问作者Priscila
相关产品推荐
相关产品推荐

