React,Jest和Material-UI:如何测试以模式或弹出方式呈现的内容 [英] React, Jest and Material-UI: How to test for content rendered in a modal or popover

查看:785
本文介绍了React,Jest和Material-UI:如何测试以模式或弹出方式呈现的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一些Material-ui组件不会将其结果呈现在其父对象放置的位置上.其中有DialogMenu

There are a few material-ui components that do not render their results in the same place as the component is placed by their parent. Among these we have the Dialog, Menu, etc.

显然,这不可能在装有某些父组件的jest.js包装器中测试其内容是否存在.

This makes it apparently impossible to test for their content's presence in a jest.js wrapper with some parent component mounted in it.

例如,给出以下组件:

class DropdownMenu extends React.Component {
  onButtonClick = (e) => {
    this.setState({ open: true, anchorEl: e.currentTarget });
  }

  render() {
    return (
      <div>
        <Button onClick={this.onButtonClick}>Menu</Button>
        <Menu
          open={this.state.open}
          onRequestClose={() => this.setState({ open: false })}
        >
          <MenuItem label="Home" />
          <MenuItem label="Sign in" />
        </Menu>
      </div>
    );
  }
}

此测试即使可以凭直觉工作也无法通过:

This test fails even though it should intuitively work:

it('renders some menu items', () => {
  const wrapper = mount(<AppMenu />);
  expect(wrapper).toContainReact(<MenuItem label="Home" />);
});

这是杰斯特失败的输出:

And this is Jest's output of the failure:

renders some menu items

Expected <AppMenu> to contain <withStyles(MenuItem) className="MenuItem" component={{...}} to={{...}}>Home</withStyles(MenuItem)> but it was not found.
HTML Output of <AppMenu>:
 <div><button tabindex="0" class="MuiButtonBase-root-3477017037 MuiButton-root-3294871568 MuiButton-flatContrast-53993421" type="button" role="button" aria-owns="simple-menu" aria-haspopup="true"><span class="MuiButton-label-49836587">Menu</span><span class="MuiTouchRipple-root-3868442396"></span></button><!-- react-empty: 5 --></div>

如您所见,就像渲染的全部是<Button>一样.确实,当您在浏览器中呈现上述组件,并展开菜单并检查其菜单项元素时,它们将呈现在DOM中的其他位置,而不是在按钮出现的位置或附近.实际上,它们是在文档<body>元素正下方的div <body><div data-mui-portal="true"> ... </div>内部呈现的.

As you can see, it's like if all that was rendered was the <Button>. And indeed, when you render the above component in a browser, and you expand the menu and inspect it's menu item elements, they are rendered elsewhere in the DOM, not within or even near the place where the button appears. They are in fact rendered inside a div <body><div data-mui-portal="true"> ... </div> directly under the document's <body> element.

那么如何测试此菜单内容?

So how can this menu contents be tested?

推荐答案

在状态更改之前,不会渲染Menu,因此您可以模拟对Button的单击,让其处理程序setState触发重新渲染,然后找到特定的MenuItem.

The Menu won't be rendered until state changes, so you can simulate a click on the Button, let its handler setState, trigger a rerender, and find the specific MenuItem.

此外,这可能无需完全安装即可完成:

Also, this can probably be done without fully mounting:

it('renders some menu items', () => {
  const wrapper = shallow(<AppMenu />);

  // find the Menu Button
  const button = wrapper.findWhere(node => node.is(Button) && n.prop('children') === 'Menu');

  // simulate a click event so that state is changed
  button.simulate('click');

  // find the Home MenuItem
  const menuItem = wrapper.findWhere(node => node.is(MenuItem) && n.prop('label') === 'Home');

  // make sure it was rendered
  expect(menuItem.exists()).toBe(true);
});

这篇关于React,Jest和Material-UI:如何测试以模式或弹出方式呈现的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆