使用ThemeProvider包裹组件时react-testing-library的userEvent.click报错
核心本质
这个错误是因为ThemeProvider传入的主题缺失动画相关配置,导致MUI Select组件触发交互时,内部动画逻辑尝试读取未定义的duration属性而抛出异常。
具体场景拆解
主题配置不完整:
MUI的组件动画(比如Select的展开/收起过渡效果)依赖主题中transitions.duration的配置项。如果你的自定义主题没有通过createTheme继承默认主题,而是手动构建的部分配置(比如只定义了颜色palette),就会缺失transitions相关的完整结构。点击Select触发动画时,代码找不到duration就会报错。makeStyles隐式依赖主题动画参数:
如果你在自定义样式中使用了theme.transitions的工具方法(比如theme.transitions.create),但主题里没配置对应的duration,渲染时生成的样式会携带未初始化的动画参数,触发组件状态变化时就会抛出错误。测试环境动画API模拟不足:
虽然react-testing-library会模拟部分浏览器API,但当ThemeProvider存在时,组件会执行完整的动画逻辑。如果测试环境中requestAnimationFrame等API的模拟不完整,可能导致动画对象初始化失败,进而出现duration未定义的情况。
验证与解决方法
补全主题配置:
确保自定义主题通过createTheme创建,自动继承默认主题的所有基础配置:import { createTheme } from '@mui/material/styles'; const theme = createTheme({ // 你的自定义配置,比如palette、typography等 });这样会自动包含默认的
transitions.duration配置。测试时禁用动画:
在测试专用的主题中直接禁用动画,避免触发相关逻辑:const testTheme = createTheme({ transitions: { disable: true, }, // 其他自定义配置 });然后在测试中用这个主题包裹组件。
手动补充动画配置:
如果必须使用自定义的动画配置,确保transitions.duration存在:const theme = createTheme({ transitions: { duration: { standard: 300, // 其他需要的时长配置 }, }, });
内容的提问来源于stack exchange,提问作者CHL

