Тестирование компонентов React с помощью Enzyme, когда компонент использует события - PullRequest
0 голосов
/ 14 января 2019

У меня было много проблем с тестированием моих реактивных компонентов, использующих преимущества событий, особенно event.target. Например, при тестировании компонента ниже;

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");
    });
});

Я получаю сообщение об ошибке «Ошибка типа: e.target.closest не является функцией». Конечно, это работает и работает в браузере, не похоже, что Enzyme запускает событие таким же образом. У меня есть эта проблема или подобное на некоторых из моих компонентов, кто-нибудь знает, как решить эту проблему или обходной путь? Некоторые из этих типов проблем были решены путем добавления { attachTo: document.body } в метод монтирования Enzyme, но не с этим.

1 Ответ

0 голосов
/ 14 января 2019

Запуск события в энзиме - не то же самое, что в браузере, на самом деле он просто берет функцию onClick и вызывает ее. Поэтому, если ваше событие относится к объекту события, вы должны передать его самостоятельно:

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

Также посмотрите документы для simulate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...