我如何浅测试包裹在备忘和withStyles中的react组件?

时间:2019-03-05 13:49:24

标签: reactjs material-ui enzyme memo

我有一个包含在Material-UI withStyles HOC和React memo HOC中的组件。

由于无法调用dive(),因此无法测试此组件:

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

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

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

有效测试此组件的可用策略有哪些?

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... */
  }
});

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);
  });
});

可正常使用的沙箱

this question

3 个答案:

答案 0 :(得分:2)

正如skyboyer建议的那样,您应该只export记忆功能。您可以import默认导出HOC并使用mount,但是您需要模拟classes对象以匹配其在组件中的使用方式。

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

components / 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());-例如{{1} })

console.log(mountHOComponent.debug());

答案 1 :(得分:0)

此问题自enzyme-adapter-react-16 v1.13.0起已得到修复,其中增加了备忘()支持。这是一个分叉的沙箱,其依赖关系已更新,以显示两种测试方法(潜水和导出解决方法)现在都通过了。

Edit Testing Composed Memo and withStyles

答案 2 :(得分:0)

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form-horizontal">
  <div class="row field_wrapper">
    <label class="col-md-offset-1 col-sm-3 control-label" for="title">Title</label>
    <div class="col-md-6 col-sm-9 col-10">
      <input id="title" class="form-control form-item required" name="input_title[]" type="text" value="" data-label="title" />
      <a href="javascript:void(0);" class="add_input_button" title="Add field">+</a>
    </div>
  </div>
</form>

所以在我的笑话测试中,我可以通过引用类型键

来获取内部组件
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 } }