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

使用Enzyme与Jest测试Material-UI Select组件时的选项加载检测问题

解决Material-UI Select下拉菜单在Enzyme测试中无法被捕获的问题

我之前也碰到过完全一样的问题!Material-UI的Select组件下拉菜单是通过Portal渲染到<body>标签下的,并不是嵌套在你的ColorSelect组件DOM树里——这就是你用wrapper.debug()看不到菜单元素的核心原因。Enzyme的mount默认只会追踪组件自身渲染的DOM节点,对Portal渲染到外部的元素无能为力。

下面是两种可行的解决方案:

方法1:将组件挂载到真实DOM节点,直接从document中查找菜单

你可以在测试时把组件挂载到一个真实的DOM元素上,然后通过document对象来查询下拉菜单的内容。修改你的测试代码如下:

import * as React from 'react';
import MockProvider from '../../mockProvider';
import * as data from '../../data/poData.json';
import { act } from '@testing-library/react';
import { mount } from "enzyme";
import ColorSelect from '../../../components/order/ColorSelect';

test("check colors dropdown loads correctly", async () => {
  // 创建一个临时DOM节点挂载组件
  const div = document.createElement('div');
  document.body.appendChild(div);

  try {
    let wrapper;
    await act(async () => {
      wrapper = mount(
        <MockProvider>
          <ColorSelect color="" colors={data.products[0].colors} />
        </MockProvider>,
        { attachTo: div } // 指定挂载到真实DOM节点
      );
      // 触发下拉菜单展开
      wrapper.find('#color-id-input').simulate('click');
    });
    wrapper.update();

    // 从document中查找Material-UI的菜单选项
    const menuItems = document.querySelectorAll('.MuiMenuItem-root');
    console.log('菜单选项数量:', menuItems.length); // 应该是3个:None + 2个颜色

    // 验证选项内容
    expect(menuItems[0].textContent).toContain('None');
    expect(menuItems[1].textContent).toContain('Pearl');
    expect(menuItems[2].textContent).toContain('Red');
  } finally {
    // 清理DOM节点,避免测试污染
    document.body.removeChild(div);
  }
});

方法2:给MenuItem添加测试标识,提升查找稳定性

为了避免依赖Material-UI的类名(不同版本可能会变化),你可以给MenuItem添加data-testid属性,这样查找会更可靠:

首先修改ColorSelect.jsx:

// 在MenuItem上添加data-testid
<MenuItem data-testid="color-select-option" style={{ fontSize: "13px" }} value="">
  <em>None</em>
</MenuItem>
{ props.colors.map(color => (
  <MenuItem 
    data-testid="color-select-option"
    key={"ColorNewLineMenuItem_" + color.colorCode} 
    style={{ fontSize: "13px" }} 
    value={color.colorCode}
  >
    <div>
      <Avatar key={"ColorNewLineAvatar_" + color.colorCode} src={color.imageSrc} />
      <div>{color.name}</div>
    </div>
  </MenuItem>
)) }

然后在测试中用这个标识查找:

// 替换之前的查询方式
const menuItems = document.querySelectorAll('[data-testid="color-select-option"]');

额外注意事项

  • 务必用await act()包裹所有异步操作,Material-UI的菜单展开是异步状态更新过程,必须等待完成后再查询元素。
  • 如果你使用的是Material-UI v5,类名是MuiMenuItem-root;如果是v4则是MuiListItem-root,记得根据版本调整。
  • 测试完成后一定要清理挂载的DOM节点,避免影响其他测试用例。

希望这些方法能帮你顺利验证下拉菜单的内容!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:29:06