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

使用Enzyme测试依赖target属性的Preact事件处理函数报错求助

解决Enzyme测试Preact组件事件处理函数时的target只读错误

这个问题我之前在Preact+Enzyme的项目里也碰到过,本质原因是:当你用Enzyme的mount和simulate方法时,适配器(这里是enzyme-adapter-preact-pure)会创建一个符合DOM规范的原生Event实例,而Event对象的target属性是只读的。你传入的{ target: { value: 'foo', name: 'name' } }会被Enzyme尝试用Object.assign合并到原生Event上,这就触发了修改只读属性的TypeError。

下面给你两种简单可行的解决方案:

方案一:直接调用事件处理函数(推荐)

跳过Enzyme的simulate方法,直接获取input组件的onChange属性并手动调用,这样可以完全自定义事件对象,避开原生Event的限制:

test('it changes the correspondent state key when input is changed', () => {
  // 找到目标input元素
  const inputElement = wrapper.find('input');
  // 直接调用它的onChange事件处理函数,传入自定义的事件对象
  inputElement.props().onChange({ 
    target: { value: 'foo', name: 'name' } 
  });
  // 验证状态是否更新
  expect(wrapper.state('name')).toEqual('foo');
});

这种方式更直接,也不会受到Enzyme适配器对事件模拟的限制,在Preact组件测试中非常实用。

方案二:构造合法的Event对象(如果坚持用simulate)

如果你一定要用simulate方法,需要手动创建一个Event实例,并用Object.defineProperty来设置只读的target属性:

test('it changes the correspondent state key when input is changed', () => {
  // 创建一个change事件实例
  const changeEvent = new Event('change');
  // 给事件对象定义target属性(因为原生Event的target是只读的,必须用这种方式)
  Object.defineProperty(changeEvent, 'target', {
    value: { value: 'foo', name: 'name' },
    enumerable: true, // 确保属性可以被枚举访问
    writable: false   // 保持只读特性,符合规范
  });
  // 用构造好的事件对象模拟change事件
  wrapper.find('input').simulate('change', changeEvent);
  expect(wrapper.state('name')).toEqual('foo');
});

额外提示

你的handleInputChange函数是复用性很强的实现,不过要确保在组件中正确绑定this(比如用箭头函数、class字段绑定,或者在constructor中bind),否则可能会出现this.setState未定义的问题——不过从你的报错信息看,当前问题和this绑定无关,只是target属性的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:51:12