【发布时间】:2018-12-18 17:42:41
【问题描述】:
问题很简单。我有一个我想测试的 material-ui 菜单适当地关闭(通过用户在菜单外单击)。
事实证明,这非常具有挑战性。这是组件(从the docs 撕下来):
class App extends React.Component {
state = {
anchorEl: null
};
handleClick = event => {
this.setState({ anchorEl: event.currentTarget });
};
handleClose = () => {
this.setState({ anchorEl: null });
};
render() {
const { anchorEl } = this.state;
return (
<div>
<Typography variant="body1"> Click Me</Typography>
<Button
aria-owns={anchorEl ? "simple-menu" : undefined}
aria-haspopup="true"
onClick={this.handleClick}
>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={this.handleClose}
>
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
}
还有测试:
const props = {
classes: {}
};
describe("test", () => {
it("closes the menu", () => {
const wrapper = mount(<App {...props} />);
wrapper.find(Button).simulate("click");
expect(wrapper.find(Menu).prop("open")).toBe(true);
wrapper.find(Typography).simulate("click");
expect(wrapper.find(Menu).prop("open")).toBe(false);
wrapper.unmount();
});
it("closes the menu a different way", () => {
const outerNode = document.createElement("div");
outerNode.setAttribute("id", "root-node");
document.body.appendChild(outerNode);
const wrapper = mount(<App {...props} />, {
attachTo: outerNode
});
wrapper.find(Button).simulate("click");
expect(wrapper.find(Menu).prop("open")).toBe(true);
outerNode.click();
expect(wrapper.find(Menu).prop("open")).toBe(false);
wrapper.unmount();
});
it("closes the menu yet a different way", () => {
const eventMap = {};
window.addEventListener = jest.fn((event, cb) => {
eventMap[event] = cb;
});
const wrapper = mount(<App {...props} />);
wrapper.find(Button).simulate("click");
expect(wrapper.find(Menu).prop("open")).toBe(true);
wrapper.find(Typography).simulate("click");
eventMap.click();
expect(wrapper.find(Menu).prop("open")).toBe(false);
wrapper.unmount();
});
});
很遗憾,这些测试都不起作用。我正在做一些挖掘,发现this SO post 链接了this github issue 解决方案和第三种方法最初来自的地方,但是,我无法让其中任何一个工作。
我用下面的代码创建了一个 CodeSandbox,供这里任何愿意提供帮助的慷慨人士使用。
【问题讨论】:
-
我认为这不是您应该编写单元测试的方式。你应该只测试你的代码。在这里,您正在尝试测试 material-ui 代码。你应该只测试你的 onClose 函数是否应该将 isOpen 状态设置为 false 并且 rest 将由 material-ui 处理,因为他们已经在他们的代码中测试了他们的逻辑。
-
我同意,但是,我喜欢测试用户如何测试/使用应用程序。我想触发关闭菜单不是通过手动触发
onClose,而是通过以onClose被调用的方式与ui交互。这也确保onClose正确连接到元素。 -
这可能是另一种保证
onClose在没有模拟onClose 的情况下被调用的方式,因为这样做的结果是关闭菜单。无论哪种方式,它都不成功。
标签: javascript reactjs jestjs enzyme