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

