6

我有一个包含在 Material-UI withStylesHOC 和 React memoHOC 中的组件。

我无法测试此组件,因为我无法调用dive()

ShallowWrapper::dive() can only be called on components

我目前知道的唯一选择是独立export Demoexport default withStyles(styles)(Demo). 这使我可以测试未包含在withStyles. 我想避免这种方法。

如果我删除 memo(),我可以测试该组件。同样,如果我删除 withStyles(),我也可以测试该组件。这些 HOC 的组合使我的组件无法测试。

有哪些可用的策略来有效地测试这个组件?

演示.js

import React, { memo } from "react";
import MUIIconButton from "@material-ui/core/IconButton";
import { withStyles } from "@material-ui/core/styles";
import Tooltip from "@material-ui/core/Tooltip";
import Typography from "@material-ui/core/Typography";

const styles = () => ({
  root: {
    backgroundColor: "red"
    /* more styles... */
  }
});

const Demo = memo(({ label, classes }) => (
  <div className={classes.root}>
    <Tooltip disableFocusListener title={label}>
      <Typography>label</Typography>
    </Tooltip>
  </div>
));

export default withStyles(styles)(Demo);

demo.test.js

import React from "react";
import Adapter from "enzyme-adapter-react-16";
import { configure, shallow } from "enzyme";
import Demo from "./demo";
import MUIIconButton from "@material-ui/core/IconButton";
import Tooltip from "@material-ui/core/Tooltip";

configure({ adapter: new Adapter() });

describe("Demo", () => {
  it("Should have a tooltip with label", () => {
    const tooltip = "My tooltip";

    const el = shallow(<Demo label={tooltip} />).dive();

    expect(el.find(Tooltip).props().title).toEqual(tooltip);
  });
});

完整的工作沙箱

编辑 2j3o14zxy0

4

3 回答 3

6

当我用备忘录包裹时,我得到一个看起来像这样的形状

import MemoizedFoo from './Foo'
console.log(MemoizedFoo) 

    { '$$typeof': Symbol(react.memo),
      type:
       { [Function: Foo]
         displayName: 'Foo',
         defaultProps: { theme: {} } },
      compare: null }

所以在我的笑话测试中,我可以通过引用类型键来获取内部组件

import MemoizedFoo from './Foo'
const Foo = MemoizedFoo.type

describe() { it() { shallow(Foo) ...etc } }

这对于浅层单元测试非常有用。

如果我正在安装父组件并寻找要在场的子组件,您可以执行以下操作:

wrapper = mount(Layout)
wrapper.find('Memo(Foo)')
于 2019-08-15T13:41:49.980 回答
4

正如skyboyer 建议的那样,您应该只export使用memoized 函数。您可以import使用默认导出HOC和利用mount,但您需要模拟classes对象以匹配它在组件中的使用方式。

工作示例https ://codesandbox.io/s/4r492qvoz9

组件/Demo/demo.js

import React, { memo } from "react";
import MUIIconButton from "@material-ui/core/IconButton";
import { withStyles } from "@material-ui/core/styles";
import Tooltip from "@material-ui/core/Tooltip";
import Typography from "@material-ui/core/Typography";

const styles = () => ({
  root: {
    backgroundColor: "red"
    /* more styles... */
  }
});

export const Demo = memo(({ label, classes }) => {
  return (
    <div className={classes.root}>
      <Tooltip disableFocusListener title={label}>
        <Typography>label</Typography>
      </Tooltip>
    </div>
  );
});

export default withStyles(styles)(Demo);

components/Demo/__tests__/demo.test.js如果需要查看DOM结构,则只需使用console.log(wrapper.debug());-- 例如console.log(mountHOComponent.debug());

import React from "react";
import Adapter from "enzyme-adapter-react-16";
import { configure, shallow, mount } from "enzyme";
import { Demo } from "../demo";
import HOCDemo from "../demo";

configure({ adapter: new Adapter() });

const initialProps = {
  label: "My tooltip",
  classes: {
    root: "component-example"
  }
};

const shallowWrapper = shallow(<Demo {...initialProps} />);
const mountWrapper = mount(<Demo {...initialProps} />);
const mountHOComponent = mount(<HOCDemo {...initialProps} />);

describe("Demo", () => {
  afterAll(() => {
    shallowWrapper.unmount();
    mountWrapper.unmount();
  });

  it("shallowWrap renders a tooltip with label", () => {
    expect(shallowWrapper.find("WithStyles(Tooltip)").props().title).toBe(
      initialProps.label
    );
  });

  it("mountWrap renders a tooltip with label", () => {
    expect(mountWrapper.find("Tooltip").props().title).toBe(initialProps.label);
  });

  it("mountHOComponent renders a tooltip with label", () => {
    expect(mountHOComponent.find("Tooltip").props().title).toBe(
      initialProps.label
    );
  });
});
于 2019-03-05T16:51:23.910 回答
0

现在从酶适配器反应 16 v1.13.0 开始修复此问题,增加了备忘录潜水()支持。这是一个更新了依赖项的分叉沙箱,以显示两种测试方法(潜水和导出解决方法)现在都通过了。

编辑测试撰写的备忘录和 withStyles

于 2019-06-05T08:32:33.567 回答