You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest Mock React函数式组件中派发Redux Action的函数并修复测试失败问题

错误原因梳理

你写的测试用例存在4个核心问题,导致断言失败:

  1. 你定义的onPostJobSubmit mock函数完全没有和组件关联,组件内部是调用useDispatch返回的dispatch方法派发action,这个mock永远不会被触发
  2. 你测试的是函数式组件,Enzyme的wrapper.instance()对函数式组件默认返回null,这行代码完全无效
  3. 模拟submit时传入的event.target字段不符合组件逻辑:组件里jobPosterId从cookie获取、department存在组件state、jobDescription从富文本编辑器实例读取,这三个字段都不会从event.target中读取,你传了也没用
  4. 没有提前填充表单值、更新组件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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 02:24:02