如何在Jest中动态模拟react-router-dom的useParams钩子?
如何在Jest中动态模拟react-router-dom的useParams钩子
你的问题出在第二种写法里,useParams被定义成了返回一个jest mock函数,而不是直接返回参数对象。组件调用useParams()时,拿到的是这个mock函数本身,而不是它的返回值,所以解构出来的hash自然为空。
下面是两种正确的实现方式,支持动态修改useParams的返回值:
方案1:提前定义可复用的mock函数
先单独定义mock版的useParams函数,在jest.mock中让模块导出这个函数,这样就能在不同测试用例里动态设置返回值:
// 提前定义可修改的mock函数 const mockUseParams = jest.fn(); const mockedUsedNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), // 保留非钩子的真实实现 useNavigate: () => mockedUsedNavigate, useParams: () => mockUseParams, })); // 测试用例1:hash为123的场景 test('render component with hash 123', () => { mockUseParams.mockReturnValue({ hash: '123' }); // 渲染组件并执行断言逻辑 }); // 测试用例2:hash为456的场景 test('render component with hash 456', () => { mockUseParams.mockReturnValue({ hash: '456' }); // 渲染组件并执行断言逻辑 });
方案2:使用jest.spyOn动态替换
这种方式不需要提前整体mock模块,而是在测试用例中单独对useParams进行mock,灵活性更高:
import { useParams, useNavigate } from 'react-router-dom'; // 提前mock useNavigate(如果业务需要) const mockedUsedNavigate = jest.fn(); jest.spyOn(require('react-router-dom'), 'useNavigate').mockReturnValue(mockedUsedNavigate); test('test with specific hash value', () => { // 针对当前用例设置useParams返回值 jest.spyOn(require('react-router-dom'), 'useParams').mockReturnValue({ hash: '123' }); // 渲染组件、执行断言 }); test('test with another hash value', () => { jest.spyOn(require('react-router-dom'), 'useParams').mockReturnValue({ hash: '456' }); // 渲染组件、执行断言 });
为什么原写法失效?
你之前的错误代码中,useParams: () => jest.fn().mockReturnValue({ hash: '123' }) 相当于每次调用useParams()都会返回一个新的jest函数,而组件期望useParams()直接返回参数对象,所以解构时自然拿不到hash字段。
内容的提问来源于stack exchange,提问作者Jeff Goes
相关产品推荐
相关产品推荐

