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

Jest + Enzyme测试中Mock函数未被调用问题求助

解决submitChoice() Mock函数点击断言失败的问题

我看到你在测试React组件时,尝试Mock负责API调用的submitChoice()函数,期望点击#buttonOption1按钮时触发它,但测试断言失败,提示Expected mock function to have been called.。结合你给出的测试代码片段,我整理了几个常见的问题点和对应的解决方案:

1. 检查Mock的方式是否匹配函数的实际定义

首先要明确submitChoice是组件的实例方法、props传入的函数,还是从外部模块导入的函数,不同的定义方式Mock的方法也不一样:

情况1:submitChoice是组件的实例方法(类组件)

如果submitChoice是类组件的实例方法,你需要Mock组件原型上的方法,而不是随便创建一个Mock函数。比如:

import React from 'react';
import App from './App';
import { mount } from 'enzyme';

describe('App', () => {
  it('should call the submitChoice method on click', async () => {
    // 1. Mock组件原型上的submitChoice方法
    const mockSubmit = jest.spyOn(App.prototype, 'submitChoice').mockResolvedValue({});
    
    const wrapper = mount(<App />);
    
    // 2. 找到按钮并触发点击事件
    wrapper.find('#buttonOption1').simulate('click');
    
    // 3. 如果submitChoice是异步函数,需要等待异步流程完成
    await new Promise(resolve => setImmediate(resolve));
    wrapper.update();
    
    // 4. 断言Mock函数被调用
    expect(mockSubmit).toHaveBeenCalled();
    
    // 5. 测试完成后清理Mock
    mockSubmit.mockRestore();
  });
});

情况2:submitChoice是通过props传入的函数

如果组件是通过props接收submitChoice,那你需要直接创建Mock函数作为props传入组件:

import React from 'react';
import App from './App';
import { mount } from 'enzyme';

describe('App', () => {
  it('should call the submitChoice method on click', () => {
    // 1. 创建Mock函数
    const mockSubmitChoice = jest.fn();
    
    // 2. 将Mock函数作为props传入组件
    const wrapper = mount(<App submitChoice={mockSubmitChoice} />);
    
    // 3. 触发按钮点击
    wrapper.find('#buttonOption1').simulate('click');
    
    // 4. 断言Mock函数被调用
    expect(mockSubmitChoice).toHaveBeenCalled();
  });
});

情况3:submitChoice是从外部模块导入的函数

如果submitChoice是从API模块导入的,比如import { submitChoice } from './api',那你需要Mock整个模块:

import React from 'react';
import App from './App';
import { mount } from 'enzyme';
import { submitChoice } from './api';

// Mock整个API模块
jest.mock('./api', () => ({
  submitChoice: jest.fn().mockResolvedValue({})
}));

describe('App', () => {
  it('should call the submitChoice method on click', async () => {
    const wrapper = mount(<App />);
    
    wrapper.find('#buttonOption1').simulate('click');
    
    await new Promise(resolve => setImmediate(resolve));
    
    expect(submitChoice).toHaveBeenCalled();
  });
});

2. 确认渲染方式是否正确

如果你用了shallow渲染,而#buttonOption1按钮在组件的子组件中,shallow不会渲染子组件,导致找不到按钮元素。这种情况下应该换成mount渲染,它会渲染整个组件树。

3. 处理异步函数的时序问题

如果submitChoice是异步函数(比如包含API调用),测试代码会在异步操作完成前执行断言,导致断言失败。你需要等待异步流程结束后再断言:

  • 可以用async/await配合setImmediate(如上例)
  • 或者使用enzyme的waitForState(如果你的组件会根据API调用结果更新state):
    await waitForState(wrapper, state => state.someStateKey !== initialValue);
    

额外检查点

  • 确认按钮的选择器#buttonOption1是否正确,比如有没有拼写错误,或者按钮的id是否真的是这个值。
  • 检查按钮的点击事件绑定是否正确,比如是不是绑定了onClick={() => this.submitChoice()},而不是其他函数。

内容的提问来源于stack exchange,提问作者Oliver

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:16:30