如何使用Jest Mock React函数式组件中派发Redux Action的函数并修复测试失败问题
错误原因梳理
你写的测试用例存在4个核心问题,导致断言失败:
- 你定义的
onPostJobSubmitmock函数完全没有和组件关联,组件内部是调用useDispatch返回的dispatch方法派发action,这个mock永远不会被触发 - 你测试的是函数式组件,Enzyme的
wrapper.instance()对函数式组件默认返回null,这行代码完全无效 - 模拟submit时传入的
event.target字段不符合组件逻辑:组件里jobPosterId从cookie获取、department存在组件state、jobDescription从富文本编辑器实例读取,这三个字段都不会从event.target中读取,你传了也没用 - 没有提前填充表单值、更新组件state,直接触发提交时组件拿不到完整的表单数据,也可能触发必填校验中断提交
修复方案
第一步:提前Mock依赖
在测试文件顶部mock所有外部依赖:
import { useDispatch } from 'react-redux'; import { getCookie } from '../../../utils/cookies'; import { postJobAction } from './redux/postJobActions'; import { EditorState, ContentState } from 'draft-js'; // Mock redux的dispatch方法 const mockDispatch = jest.fn(); jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), useDispatch: () => mockDispatch, useSelector: jest.fn() })); // Mock cookie读取方法 jest.mock('../../../utils/cookies', () => ({ getCookie: jest.fn((key) => key === 'id' ? '12312jkh3kj12h3k12h321g3' : '') })); // Mock action创建函数,方便校验入参 jest.mock('./redux/postJobActions', () => ({ postJobAction: jest.fn() }));
第二步:重写测试用例
it('should submit job post form on save button click', () => { // 用mount完整渲染组件,确保子组件也能正常渲染 const wrapper = mount(<PostJobComponent />); // 填充职位标题 wrapper.find('input[name="title"]').simulate('change', { target: { value: 'some value' } }); // 填充工作地点 wrapper.find('input[name="location"]').simulate('change', { target: { value: 'some value' } }); // 选择部门,触发onChange更新state wrapper.find('select.job__department').simulate('change', { target: { value: 'Customer Success' } }); // 手动设置富文本编辑器内容 const mockEditorState = EditorState.createWithContent(ContentState.createFromText('This is Job description.')); wrapper.find('Editor').prop('onEditorStateChange')(mockEditorState); // 模拟表单提交 wrapper.find('form').simulate('submit', { preventDefault: jest.fn() }); // 断言逻辑 expect(mockDispatch).toHaveBeenCalled(); expect(postJobAction).toHaveBeenCalledWith({ jobPosterId: '12312jkh3kj12h3k12h321g3', title: 'some value', location: 'some value', department: 'Customer Success', jobDescription: 'This is Job description.' }); });
注意事项
组件单元测试只需要覆盖组件本身的逻辑:正确收集表单数据、正确派发action即可。saga、service的逻辑属于独立的业务层,应该单独写测试用例覆盖,不需要在组件测试中耦合这部分逻辑。
内容的提问来源于stack exchange,提问作者Om3ga
相关产品推荐
相关产品推荐

