使用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
相关产品推荐
相关产品推荐

