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

使用Enzyme/Jest测试React组件点击事件时遇expect(jest.fn())报错

解决Enzyme/Jest测试中模拟点击触发props函数失败的问题

看起来你的测试遇到了两个小问题:一是Sinon Spy和Jest断言的兼容冲突,二是点击事件的触发目标选择不太妥当。咱们一步步来解决:

问题根源拆解

错误提示jest.fn() value must be a mock function or spy. Received: function: [Function proxy],本质是你用了Sinon创建的Spy函数,却试图用Jest内置的toHaveBeenCalled()断言去验证它——Jest的这个断言只认自己生成的Mock函数,对Sinon的Spy不兼容。另外,你模拟点击的是<i>图标元素,但组件的onClick事件其实绑定在父级<a>标签上,虽然事件冒泡理论上能触发父元素事件,但直接触发事件绑定的元素更稳妥,能避免不必要的意外。

两种可行解决方案

方案1:改用Jest原生Mock函数(推荐)

放弃Sinon,直接用Jest自带的jest.fn()创建Mock函数,和Jest的断言体系完美兼容:

import expect from 'expect';
import React from 'react';
import { shallow } from 'enzyme';
import ToggleSideNavComponent from './ToggleSideNavComponent';

function setup() {
  // 用Jest原生Mock替代Sinon Spy
  const props = {
    handleSideNavToggle: jest.fn()
  };
  return {
    props: props,
    wrapper: shallow(<ToggleSideNavComponent {...props} />)
  };
}

describe('ToggleSideNavComponent', () => {
  it('should render menu icon and trigger toggle function on click', () => {
    const { props, wrapper } = setup();
    // 直接找到绑定onClick的<a>元素模拟点击
    wrapper.find('#toggle_sidebar_btn').simulate('click');
    
    // Jest断言可以正常识别自己的Mock函数
    expect(props.handleSideNavToggle).toHaveBeenCalled();
    // 验证菜单图标存在
    expect(wrapper.find('#menu').length).toBe(1);
  });
});

方案2:继续使用Sinon,改用Sinon专属断言

如果你习惯用Sinon,需要换成Sinon自己的断言方法来检查Spy是否被调用:

import expect from 'expect';
import React from 'react';
import { shallow } from 'enzyme';
import ToggleSideNavComponent from './ToggleSideNavComponent';
import sinon from 'sinon';

function setup() {
  const props = {
    handleSideNavToggle: sinon.spy()
  };
  return {
    props: props,
    wrapper: shallow(<ToggleSideNavComponent {...props} />)
  };
}

describe('ToggleSideNavComponent', () => {
  it('should render menu icon and trigger toggle function on click', () => {
    const { props, wrapper } = setup();
    wrapper.find('#toggle_sidebar_btn').simulate('click');
    
    // 使用Sinon的断言方法验证Spy调用
    sinon.assert.calledOnce(props.handleSideNavToggle);
    expect(wrapper.find('#menu').length).toBe(1);
  });
});

额外小贴士

  • 尽量直接模拟绑定了onClick事件的元素,不要选择它的子元素,避免事件冒泡失效等意外情况导致测试不稳定。
  • 新版本Jest的Mock工具和自身生态(断言、覆盖率统计等)整合度更高,优先使用原生Mock能减少第三方依赖带来的兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:55:11