使用Jest+Enzyme测试无状态Material-UI TextField时值不更新问题
解决Jest+Enzyme测试Material-UI TextField无状态组件时value不更新的问题
看起来你遇到的问题核心是受控组件的特性——你的Textfield是一个无状态受控组件,它的value完全由传入的props决定,模拟change事件只会触发你传入的onChange回调,但不会自动修改组件的value值,因为组件本身不维护内部状态。
问题分析
你的测试代码里,模拟change事件后,并没有更新传入组件的value props,所以组件依然会渲染props里初始的"Hello World",这就是第二个断言失败的原因。而第一个断言expect(handleChange).toHaveBeenCalled()应该是能通过的,只要你的组件正确传递了onChange。
修正后的测试代码
要验证value更新后的显示,你需要手动更新组件的props,模拟父组件更新状态后的行为,再重新渲染组件:
it("on input change should call onChange function passed through props and update value",()=>{ const handleChange = jest.fn(); let props = { label: 'Test Label', type: 'text', name: 'email', value: "Hello World", index: 0, input: {}, defaultValue:'default', meta: { touched: true, error: 'error' }, onChange:handleChange, error: true // 注意:组件解构了props.error,原测试未传递,补上避免警告 } const wrapper = mount(<Textfield {...props}/>); // 第一步:模拟change事件,验证onChange被正确调用 wrapper.find('input').simulate('change',{target:{name:'email',value:"hello"}}); expect(handleChange).toHaveBeenCalledWith(expect.objectContaining({ target: {name:'email',value:"hello"} })); // 第二步:更新props的value,模拟父组件更新状态 wrapper.setProps({ value: "hello" }); wrapper.update(); // 现在断言input的value是否正确渲染 expect(wrapper.find('input').prop('value')).toBe("hello") })
额外注意点
- 你的
Textfield组件里解构了props.error,但原测试的props里没有传递这个属性,而是在meta.error里,这可能导致组件的error状态不符合预期,建议调整组件内的取值逻辑:// 在Textfield组件里修改error的取值 const {label,value,onChange,className,name,id,onKeyDown,multiline,index,inputProps,isDisabled, meta} = props; const error = meta?.error; - Material-UI的
TextField的类名属性是驼峰式的className,你的组件里写的是classname={className},这里应该改成className={className},否则自定义样式不会生效。
内容的提问来源于stack exchange,提问作者Vrushali Bhosale
相关产品推荐
相关产品推荐

