从 MaterialUI v4 升级到 MaterialUI v5 后 - 缺少默认主题导致挂载测试失败。如何恢复默认主题?

IT技术 reactjs material-ui mocha.js enzyme
2022-07-16 02:03:16

在我的 mocha 测试代码中,我有很多使用 mount 的测试。

enzyme.mount(<SomeComponentThatUsesMUI />);

这在 material-ui v4 中运行良好。但是在 v5 中,由于缺少默认主题,任何SomeComponentThatUsesMui尝试访问主题的代码

现在我知道可以用 ThemeProvider 包装组件:

 enzyme.mount(<ThemeProvider theme={} ><<SomeComponentThatUsesMUI /><ThemeProvider />);

然而,这意味着后续的测试代码需要调整,这是 100 多个测试。(我测试的 5%)。

有没有办法为单元测试恢复默认主题?

2个回答

警告:这个答案修改了两个内部字段(因为它们在 React 17.0.2 中)。

如果 React Context 对象在内部发生变化,这将中断


null默认主题的原因来自:

@mui/private-theming/node/useTheme/ThemeContext.js

const ThemeContext = /*#__PURE__*/React.createContext(null);

当为 ThemeContext 调用 createContext 时,没有设置默认主题。

因此可以添加单元测试设置代码(在您的单元测试运行之前):

import { createTheme } from '@mui/material/styles';

import('@mui/private-theming/node/useTheme/ThemeContext.js').then(ThemeContext => 
{
  let defaultTheme = React.createContext(createTheme({}));
  if (ThemeContext.default)
  {
    ThemeContext.default._currentValue = defaultTheme._currentValue;
    ThemeContext.default._currentValue2 = defaultTheme._currentValue2;
  }  
});

这会修改两个内部字段,_currentValue_currentValue2将默认 ThemeContext 调整为等效于

const ThemeContext = /*#__PURE__*/React.createContext(createTheme({}));

尽管此答案需要修改每个 mount 语句,但不需要对测试代码进行任何后续更改。

提供wrappingComponentwrappingComponentPropsargs 挂载:

let wrapper = enzyme.mount(<SomeComponentThatUsesMUI />,
            {
                wrappingComponent: ThemeProvider,
                wrappingComponentProps: { theme: createTheme({}) }
            });

SomeComponentThatUsesMUI现在有一个主题,但 wrapper 仍然是指SomeComponentThatUsesMUI而不是 ThemeProvider。