在测试利用事件(特别是event.target
)的react组件时遇到了很多麻烦。例如,当测试下面的组件时;
import * as React from 'react';
import { generateGuid } from '../../../utilities/GuidGenerator';
export interface Props {
dropdownToggle: JSX.Element;
dropdownMenu: JSX.Element;
}
class Dropdown extends React.PureComponent<Props, object> {
id = "d".concat(generateGuid().slice(0, 7));
componentDidMount() {
window.addEventListener("click", this.hideMenu);
}
componentWillUnmount() {
window.removeEventListener("click", this.hideMenu);
}
state = {
display: { "display": "none" }
}
toggleDropdown = () => {
var display = this.state.display.display === "none" ? "block" : "none";
this.setState({
display: { "display": display }
});
}
hideMenu = (e: MouseEvent) => {
if (!(e.target as HTMLElement).closest(`#${this.id}`) && !(e.target as HTMLElement).closest(".noClose")) {
this.setState({
display: { "display": "none" }
});
}
}
public render() {
return (
<div className="dropdown" >
<div id={this.id} className="dropdownToggle" onClick={this.toggleDropdown} >
{this.props.dropdownToggle}
</div>
<div style={this.state.display} className="dropdownMenu" onClick={(e: any) => { this.hideMenu(e) }} >
{this.props.dropdownMenu}
</div>
</div>
);
}
}
export default Dropdown;
...下面的测试
import * as React from 'react';
import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
import Dropdown from './Dropdown';
Enzyme.configure({ adapter: new Adapter() });
var dropdown = Enzyme.mount(<Dropdown dropdownMenu={<div></div>} dropdownToggle={<div></div>} />, { attachTo: document.body });
describe('Dropdown', () => {
test('dropdownMenu onClick function sets display to { "display": "none" } if parent is not toggle and doesn\'t contain noClose class', () => {
dropdown.find('.dropdownToggle').at(0).simulate('click');
expect(dropdown.find('.dropdownMenu').at(0).prop("style")).toHaveProperty("display", "block");
dropdown.find('.dropdownMenu').at(0).simulate('click');
expect(dropdown.find('.dropdownMenu').at(0).prop("style")).toHaveProperty("display", "none");
});
});
我收到错误“ TypeError:e.target.closest不是函数”。当然可以,并且可以在浏览器中使用,似乎Enzyme不会以相同的方式触发事件。我的几个组件出现此问题或类似问题,有人知道如何解决此问题或解决方法吗?通过将{ attachTo: document.body }
添加到Enzyme的mount方法中,解决了其中一些问题。
答案 0 :(得分:1)
在酶中引发事件与在浏览器中引发事件不同,实际上它只是采用onClick
函数并调用它。因此,如果您的事件确实存在于事件对象上,则必须自己传递它:
dropdown.find('.dropdownMenu').at(0).simulate('click' {
target: {
closest:() => {}
})
还可以查看simulate
的{{3}}