如何强制触发hover测试Material-UI(v5+)组件悬停样式
如何强制触发Material-UI v5+组件hover状态完成样式测试
以下以Button组件为例说明可直接落地的方案:
前置注意事项
- 组件本身运行时hover效果正常,问题仅出在测试环节
- 调试时发现背景色始终为初始值的核心原因是jsdom不支持CSS伪类的自动样式匹配,仅靠触发鼠标事件无法应用hover样式
- 方案兼容基于
createTheme创建的自定义主题测试场景
问题原因
你之前尝试的fireEvent.mouseEnter、fireEvent.mouseOver、userEvent.hover等方法,只会触发DOM层的鼠标事件回调,但jsdom作为轻量DOM测试实现,没有完整浏览器的CSS渲染引擎能力,不会自动匹配:hover伪类对应的样式规则,因此样式始终停留在初始状态。
正确实现方式
MUI v5 所有组件的状态都有对应的固定类名,hover状态对应的类名为Mui-hover,测试时只需要手动给目标元素添加这个类名,就能强制组件应用hover状态下的样式,无需模拟鼠标事件。
修正后的测试代码
import React from 'react'; import { render, screen } from '@testing-library/react'; import { Button } from '@mui/material'; describe('Testing hover on Button from @mui ', () => { it('Hover', async () => { const defaultBackgroundColor: string = '#b3c'; const hoverBackgroundColor: string = '#ccc'; render( <Button data-testid="button" style={{ backgroundColor: defaultBackgroundColor }} sx={{ '&:hover': { // 移除原代码里的!important,sx样式默认优先级足够,避免测试环境优先级判断异常 backgroundColor: hoverBackgroundColor } }} > MyButtonWithHover </Button> ); const buttonEl: HTMLButtonElement = screen.getByTestId('button'); // 初始状态样式校验 expect(buttonEl).toHaveStyle(` background-color: ${defaultBackgroundColor}; `); // 强制触发hover状态 buttonEl.classList.add('Mui-hover'); // hover后样式校验 expect(buttonEl).toHaveStyle(` background-color: ${hoverBackgroundColor}; `); }); });
自定义主题适配
如果需要测试createTheme创建的自定义主题下的hover样式,只需要在render时用ThemeProvider包裹组件传入自定义主题即可,hover状态的触发方式保持不变,示例:
import { createTheme, ThemeProvider } from '@mui/material'; // 你的自定义主题配置 const customTheme = createTheme({ palette: { primary: { main: '#1976d2' } } }); // 渲染时包裹主题容器 render( <ThemeProvider theme={customTheme}> <Button data-testid="button" style={{ backgroundColor: defaultBackgroundColor }} sx={{ '&:hover': { backgroundColor: hoverBackgroundColor } }} > MyButtonWithHover </Button> </ThemeProvider> );
提示:其他MUI组件状态测试也可以用同类名方案,比如聚焦状态对应
Mui-focusVisible、选中状态对应Mui-selected、禁用状态对应Mui-disabled。
内容的提问来源于stack exchange,提问作者Henrique Holtz
相关产品推荐
相关产品推荐

