material-ui - 使用 Hooks API 和 Enzyme 浅渲染测试 Material UI 组件

标签 material-ui enzyme react-hooks

最新版本的 Material UI 现在有一个 Hooks 替代品来为组件设置样式,而不是 HoC。所以不是

const styles = theme => ({
  ...
});

export const AppBarHeader = ({ classes, title }) => (
  ...
);
export default withStyles(styles)(AppBarHeader);

您可以选择这样做:

const useStyles = makeStyles(theme => ({
  xxxx
}));

const AppBarHeader = ({ title }) => {
  const classes = useStyles();
  return (
    ....
  )
};

export default AppBarHeader;

在某些方面这更好,但是对于所有钩子(Hook),您不能再向组件注入(inject)“ stub ”依赖项。以前,为了使用 Enzyme 进行测试,我只测试了非样式化组件:

describe("<AppBarHeader />", () => {
  it("renders correctly", () => {
    const component = shallow(
      <AppBarHeader title="Hello" classes="{}" />
    );
    expect(component).toMatchSnapshot();
  });
});

但是,如果你使用钩子(Hook),没有类的“ stub ”依赖,你会得到:

  Warning: Material-UI: the `styles` argument provided is invalid.
  You are providing a function without a theme in the context.
  One of the parent elements needs to use a ThemeProvider.

因为您始终需要一个适当的提供者。我可以去总结一下:

describe("<AppBarHeader />", () => {
  it("renders correctly", () => {
    const component = shallow(
      <ThemeProvider theme={theme}>
        <AppBarHeader title="Hello" classes="{}" />
      </ThemeProvider>
    ).dive();
    expect(component).toMatchSnapshot();
  });
});

但这似乎不再呈现组件的子组件(即使使用 dive 调用)。人们是如何做到这一点的?

最佳答案

编辑:根据下面的评论,此实现存在一些时间问题。考虑使用挂载而不是浅层测试进行测试,或者使用 withStyles HOC 并导出您的组件以进行浅层渲染。

所以我已经为此苦苦挣扎了一天。这是我想出的。

尝试 stub makeStyles 时出现一些问题,因为 MUI 似乎已将其设为只读。因此,我没有在每个组件中创建一个 useStyles Hook ,而是创建了我自己的自定义 useStyles Hook 来调用 makeStyles。通过这种方式,我可以 stub 我的 useStyles Hook 用于测试目的,对我的代码流的影响最小。

// root/utils/useStyles.js
// My custom useStyles hook

import makeStyles from '@material-ui/styles/makeStyles';

export const useStyles = styles => makeStyles(theme => styles(theme))();

它几乎就像使用 withStyles HOC

// root/components/MyComponent.js
import React from 'react';
import { useStyles } from '../util/useStyles';

// create styles like you would for withStyles
const styles = theme => ({
  root: {
    padding: 0,
  },
});

export const MyComponent = () => {
  const classes = useStyles(styles);
  return(
    </>
  );
}
// root/component/MyComponent.spec.js
import { MyComponent } from './MyComponent';
import { shallow } from 'enzyme';
import { stub } from 'sinon';

describe('render', () => {
  it('should render', () => {
    let useStylesStub;
    useStylesStub = stub(hooks, 'useStyles');
    useStylesStub.returns({ });
    const wrapper = shallow(<MyComponent />);
    console.log('profit');
  });
});

这是我目前能想到的最好的办法,但随时欢迎您提出建议。

关于material-ui - 使用 Hooks API 和 Enzyme 浅渲染测试 Material UI 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56020711/

相关文章:

javascript - React MaterialUI - 单击按钮后在 TextField 组件上设置错误

reactjs - 为什么我收到以下错误 : Enzyme Internal Error: configured enzyme adapter did not inherit from the EnzymeAdapter base class

javascript - 为什么我使用 jest-dom 时会报错 "TypeError: expect(...).not.toBeVisible is not a function"

reactjs - jest.mock(module) 和 jest.fn() 有什么区别

reactjs - MUI Material UI React Hook useTheme() 是遗留的,有什么替代方案?

javascript - 更改 useEffect 中的状态不会更改界面

javascript - 如何为侧边栏中的每个部分制作不同的应用栏? [ReactJs]

reactjs - 如何在内容之后重复一个字符,并将其填充到宽度的 100%? JSX/ react

reactjs - React Material UI 工具提示禁用动画

javascript - 如何解决错误 - 尝试在 react native 视频中加载空源