组件使用事件时使用酶测试React组件

时间:2019-01-14 15:14:10

标签: reactjs typescript enzyme

在测试利用事件(特别是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方法中,解决了其中一些问题。

1 个答案:

答案 0 :(得分:1)

在酶中引发事件与在浏览器中引发事件不同,实际上它只是采用onClick函数并调用它。因此,如果您的事件确实存在于事件对象上,则必须自己传递它:

 dropdown.find('.dropdownMenu').at(0).simulate('click' { 
  target: { 
    closest:() => {}
  })

还可以查看simulate的{​​{3}}