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

如何使用Enzyme测试MUI Autocomplete组件的输入值变更

测试失败的原因
  • 事件模拟参数错误:input.simulate('change', 'John') 写法不符合Enzyme事件模拟规范,change事件的第二个参数需要传入标准事件对象,而非直接传递输入值。
  • MUI Autocomplete事件封装问题:Autocomplete组件内部对输入事件做了封装拦截,直接模拟原生input的change事件无法触发组件暴露的onInputChange/onChange回调,也不会同步更新组件绑定的value值。
  • 测试取值写法错误:input.props('value') 用法不对,prop()如果传参需要传入属性名字符串,正确写法是input.prop('value'),原写法返回的是完整props对象,无法正确匹配预期值。
  • 组件本身存在类型错误:组件内状态初始值设为了空数组[],但freeSolo模式下输入的值是字符串类型,类型不匹配会导致状态更新异常。
  • 未触发组件状态更新:模拟事件后没有调用wrapper.update()同步组件最新状态,拿到的始终是初始渲染的props值。
正确测试方案

首先修正组件的初始状态错误:

const WithMaterialUI = () => {
  // 初始值改为空字符串,和输入值类型匹配
  const [data, setData] = React.useState('');
  return (
    <Autocomplete
      freeSolo
      disablePortal
      id="combo-box-demo"
      name="test"
      options={["2", "3"]}
      onInputChange={(_, val) => {
        setData(val);
      }}
      onChange={(_, val) => {
        setData(val);
      }}
      value={data}
      sx={{ width: 300 }}
      renderInput={(params) => (
        <TextField name="test" {...params} label="Movie" />
      )}
    />
  );
};

测试代码两种可选方案:

方案1:直接调用Autocomplete的onInputChange回调(更稳定,不受组件内部封装影响)

import {mount} from "enzyme";
import Autocomplete from '@mui/material/Autocomplete';
import AutocompleteComponent from "./Autocomplete";

describe('autocomplete', () => {
    test('should trigger on change and update input value', () => {
        const wrapper = mount(<AutocompleteComponent/>);
        // 找到Autocomplete组件实例,调用onInputChange回调
        wrapper.find(Autocomplete).invoke('onInputChange')({}, 'John');
        // 同步组件状态
        wrapper.update();
        // 取值验证
        const input = wrapper.find('input');
        expect(input.prop('value')).toBe('John');
    })
})

方案2:正确模拟原生输入事件

如果要走真实输入触发逻辑,可以按标准事件格式模拟,部分版本MUI需要先触发focus确保事件监听生效:

import {mount} from "enzyme";
import AutocompleteComponent from "./Autocomplete";

describe('autocomplete', () => {
    test('should trigger on change and update input value', () => {
        const wrapper = mount(<AutocompleteComponent/>);
        const input = wrapper.find('input');
        // 先触发focus激活输入框
        input.simulate('focus');
        // 传入标准事件对象模拟输入
        input.simulate('change', { target: { value: 'John' } });
        wrapper.update();
        expect(input.prop('value')).toBe('John');
    })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:06:00