如何在Jest单元测试中模拟PnP Icon Picker的图标选择操作?
解决PnP Icon Picker在Jest测试中无法模拟图标选择的问题
问题原因分析
你遇到的核心问题是PnP Icon Picker属于封装后的组件(从终端显示的<iconpicker>标签来看,大概率是Web Component),Jest默认不会渲染其内部Shadow DOM;另外如果组件的弹窗是通过React Portal挂载到body等外部节点,当前测试容器也无法捕获到这些内部元素。
解决方案
方案1:直接模拟onSave回调(推荐用于单元测试)
单元测试的核心是验证你的组件逻辑,而非第三方组件的内部交互。可以跳过组件内部操作,直接触发onSave回调来模拟图标选择:
// 1. 定义mock回调函数 const mockOnSave = jest.fn(); // 2. 渲染IconPicker时传入mock回调 render( <IconPicker data-testid="iconpicker" buttonLabel="Choose icon..." renderOption="panel" onSave={mockOnSave} /> ); // 3. 直接调用回调,模拟选择"AddFavorite"图标 mockOnSave("AddFavorite"); // 4. 验证回调触发及参数正确性 expect(mockOnSave).toHaveBeenCalledWith("AddFavorite"); // 若父组件有状态更新,可继续验证状态变化,比如: // expect(screen.getByTestId("current-icon")).toHaveTextContent("AddFavorite");
方案2:访问Web Component的Shadow DOM
如果组件的Shadow DOM是开放的(mode: 'open'),可以直接通过shadowRoot访问内部元素:
const iconPicker = screen.getByTestId("iconpicker"); // 点击打开图标面板 fireEvent.click(iconPicker); // 获取组件的Shadow DOM const shadowRoot = iconPicker.shadowRoot; // 在Shadow DOM内查找目标图标(需根据组件实际结构调整选择器) const addFavoriteIcon = shadowRoot.querySelector('[data-icon="AddFavorite"]'); expect(addFavoriteIcon).toBeInTheDocument(); userEvent.click(addFavoriteIcon);
注意:如果组件的Shadow DOM是关闭状态(mode: 'closed'),此方法无效。
方案3:处理Portal渲染的弹窗
若图标面板通过React Portal挂载到document.body,需指定容器为body来查找元素:
const iconPicker = screen.getByTestId("iconpicker"); fireEvent.click(iconPicker); // 在body容器内查找图标按钮 const addFavoriteIconButton = await screen.findByText("AddFavorite", { container: document.body }); expect(addFavoriteIconButton).toBeInTheDocument(); userEvent.click(addFavoriteIconButton);
额外提示
- 查看PnP Icon Picker官方文档,确认是否提供了测试相关的API(比如允许为内部元素添加自定义
data-testid)。 - 若为Web Component,需确保Jest配置支持Web Component,可安装
@webcomponents/webcomponentsjs并在测试启动文件中导入。
内容的提问来源于stack exchange,提问作者andré marquis
相关产品推荐
相关产品推荐

