如何使用Jest模拟测试React组件中的useSelector与useDispatch Hooks
解决方案
前置准备
确保你已经安装了以下必要依赖:@testing-library/react、react-redux、jest。
测试代码实现
1. 模拟react-redux的Hooks及外部依赖
在测试文件顶部先完成全局mock,避免组件内调用真实的Redux方法报错:
import { render, waitFor } from '@testing-library/react'; import { useSelector, useDispatch } from 'react-redux'; import Finaltable from './你的Finaltable组件路径'; // 导入你用到的其他依赖,比如sagaActions、postScanListAPI等 import { sagaActions } from './你的saga配置路径'; import { postScanListAPI } from './你的api文件路径'; // 全局mock react-redux的两个核心Hooks jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), useSelector: jest.fn(), useDispatch: jest.fn(), })); // 模拟组件用到的其他外部依赖 jest.mock('./你的api文件路径', () => ({ postScanListAPI: jest.fn().mockResolvedValue({ headers: { 'total-count': 100 }, data: [] }) })); jest.spyOn(window, 'getCookie').mockReturnValue('');
2. 编写测试用例
在每个测试用例执行前重置mock状态,避免用例之间的数据污染:
describe('Finaltable组件测试', () => { const mockDispatch = jest.fn(); beforeEach(() => { // 重置所有mock的调用记录 jest.clearAllMocks(); // 模拟useDispatch返回mock函数 useDispatch.mockReturnValue(mockDispatch); }); // 测试useSelector正常获取account_id的场景 test('useSelector在user存在时正确返回crm_account_id', async () => { // 构造测试用的Redux state useSelector.mockImplementation(selector => selector({ app: { user: { crm_account_id: 'test_account_001' } } })); render(<Finaltable />); // 验证dispatch被正确调用,触发FETCH_DATA_SAGA expect(mockDispatch).toHaveBeenCalledWith({ type: sagaActions.FETCH_DATA_SAGA }); // 验证接口调用正确携带了account_id参数 await waitFor(() => { expect(postScanListAPI).toHaveBeenCalledWith(expect.objectContaining({ account_id: 'test_account_001' })); }); }); // 测试useSelector在user不存在时返回空字符串的场景 test('useSelector在user不存在时返回空字符串', async () => { useSelector.mockImplementation(selector => selector({ app: {} })); render(<Finaltable />); await waitFor(() => { expect(postScanListAPI).toHaveBeenCalledWith(expect.objectContaining({ account_id: '' })); }); }); })
注意事项
- 组件内用到的所有外部依赖(比如
GetPager、getCookie等)都需要提前完成mock,避免依赖缺失导致的报错。 - 测试异步逻辑时必须使用
waitFor或者find*系列查询方法,等待异步请求、状态更新完成后再做断言。
内容的提问来源于stack exchange,提问作者sudhir kumar
相关产品推荐
相关产品推荐

