Ern*_*sto 7 testing reactjs jestjs material-ui enzyme
有一些material-ui组件无法将其结果与父组件放置在同一位置。其中,我们有Dialog,Menu等等。
显然,这不可能在装有某些父组件的jest.js包装器中测试其内容是否存在。
例如,给定以下组件:
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
即使此测试应直观地起作用,它也会失败:
it('renders some menu items', () => {
const wrapper = mount(<AppMenu />);
expect(wrapper).toContainReact(<MenuItem label="Home" />);
});
Run Code Online (Sandbox Code Playgroud)
这是杰斯特失败的输出:
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>
Run Code Online (Sandbox Code Playgroud)
如您所见,就好像渲染的全部是<Button>。确实,当您在浏览器中呈现上述组件,并展开菜单并检查其菜单项元素时,它们将呈现在DOM中的其他位置,而不是在按钮出现的位置内或附近。实际上,它们是在<body><div data-mui-portal="true"> ... </div>文档<body>元素正下方的div中呈现的。
那么如何测试此菜单内容?
小智 5
是的,这可能很棘手。这个问题有两个方面:
<AppMenu />- 正如您所指出的,它们在 DOM 中的其他地方。对于菜单项,您需要将它们定位到它们实际所在的位置。打开菜单的按钮位于您的包装元素中,但菜单和菜单项不会,因此您需要按角色获取菜单,然后您可以通过文本获取菜单中的项目。
这是我如何使用 React 测试库执行此操作的示例。
import React, { ReactElement } from "react";
import { render, screen } from "@testing-library/react";
import AppMenu from "./AppMenu";
import { getByText, fireEvent, getByLabelText } from "@testing-library/react";
test("It renders some menu items", async () => {
const { container } = render(<AppMenu />);
const button = getByText(container, "Menu");
fireEvent.click(button);
const menuItem = screen.getByRole("menu");
expect(await getByLabelText(menuItem, "Home")).toBeTruthy();
expect(await getByLabelText(menuItem, "Sign in")).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)
在状态发生变化之前不会Menu被渲染,因此您可以模拟单击Button,让其处理程序setState触发重新渲染,并找到特定的MenuItem.
此外,这可能可以在不完全安装的情况下完成:
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);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2251 次 |
| 最近记录: |