По своей структуре энзим не поддерживает прослушиватели событий, поскольку они являются реализацией Javascript, а не реализацией React .Таким образом, вам придется выполнить некоторые хитрости Javascript и Jest, чтобы подражать слушателю событий.
В этом случае вам действительно не нужно тестировать обработчик событий, поскольку вы просто манипулируете состоянием.Обойдя прослушиватель событий, вы можете вручную манипулировать свойством класса onClick
и утверждать, как соответствующим образом изменяются состояние и DOM - это будет более ориентированный на React тест.Однако даже это немного усложняет задачу, поскольку onClick
ожидает настоящий узел DOM.Таким образом, еще более простой подход состоит в том, чтобы просто манипулировать состоянием непосредственно с помощью wrapper.setState({ ... })
и делать утверждения против изменений DOM.
В дополнение к этому, я предпочитаю использовать className
s вместо data-attributes
, поскольку ониболее полезны для стилей и тестирования , и они не загрязняют DOM множеством ненужных и / или неиспользуемых свойств.
Приведенный ниже пример охватывает все3 варианта.
- ClickHandlerEvent.test.js (имитировать событие)
- ClickHandlerHandleClick.test.js (имитировать handleClick)
- ClickHandler.test.js (манипулировать состоянием)
Рабочий пример (нажмите вкладку Tests
- расположена справа от Browser
- для запуска всех тестов):
компонентов / ClickHandler / index.js (компонент)
import React, { Fragment, Component } from "react";
import ClickBox from "../ClickBox";
class ClickHandler extends Component {
state = {
isVisible: false
};
componentDidMount = () => {
document.addEventListener("mousedown", this.handleClick);
};
componentWillUnmount = () => {
document.removeEventListener("mousedown", this.handleClick);
};
handleClick = ({ target }) => {
this.setState({
isVisible: this.wrapperRef && this.wrapperRef.contains(target)
});
};
render = () => {
const { isVisible } = this.state;
return (
<div className="wrapper" ref={node => (this.wrapperRef = node)}>
<ClickBox>
<p className="instruction">
(click <strong>{isVisible ? "outside" : "inside"}</strong> the box
to <strong>{isVisible ? "hide" : "show"}</strong> the message)
</p>
<h2 className="message">
{isVisible ? (
<Fragment>
Hello <strong>World</strong>!
</Fragment>
) : null}
</h2>
</ClickBox>
</div>
);
};
}
export default ClickHandler;
Вариант 1
компонентов / ClickHandler / __ tests __ / ClickHandlerEvent.test.js (имитировать событие)
import React, { Fragment } from "react";
import { mount } from "enzyme";
import ClickHandler from "../index";
const initialState = {
isVisible: false
};
// elevating the event listener to the test
const eventListener = {};
document.addEventListener = (evt, cb) => (eventListener[evt] = cb);
describe("Click Handler", () => {
let wrapper;
beforeAll(() => {
wrapper = mount(
<Fragment>
<ClickHandler />
<div className="outside" />
</Fragment>
);
wrapper.setState({ ...initialState });
});
afterAll(() => {
wrapper.unmount();
});
it("renders without errors and the message should be hidden", () => {
expect(wrapper.find("div.wrapper")).toHaveLength(1);
expect(wrapper.find("h2.message").text()).toEqual("");
});
it("displays a message when a click is inside of the box", () => {
// manually triggering the event listener with a node
// inside of "ClickHandler"
eventListener.mousedown({
target: wrapper
.find("ClickHandler")
.getDOMNode()
.getElementsByClassName("instruction")[0]
});
expect(wrapper.find("ClickHandler").state("isVisible")).toBeTruthy();
expect(wrapper.find("h2.message").text()).toEqual("Hello World!");
});
it("hides the message when the click is outside of the box", () => {
// manually triggering the event listener with a node
// outside of "ClickHandler"
eventListener.mousedown({
target: wrapper.find("div.outside").getDOMNode()
});
expect(wrapper.find("ClickHandler").state("isVisible")).toBeFalsy();
expect(wrapper.find("h2.message").text()).toEqual("");
});
});
Опция 2
Компоненты / ClickHandler / __ tests __ / ClickHandlerHandleClick.test.js (мнемосхема handleClick)
import React, { Fragment } from "react";
import { mount } from "enzyme";
import ClickHandler from "../index";
const initialState = {
isVisible: false
};
describe("Click Handler", () => {
let wrapper;
beforeAll(() => {
wrapper = mount(
<Fragment>
<ClickHandler />
<div className="outside" />
</Fragment>
);
wrapper.setState({ ...initialState });
});
afterAll(() => {
wrapper.unmount();
});
it("renders without errors and the message should be hidden", () => {
expect(wrapper.find("div.wrapper")).toHaveLength(1);
expect(wrapper.find("h2.message").text()).toEqual("");
});
it("displays a message when a click is inside of the box", () => {
// manually triggering the handleClick class property with a
// node inside of "ClickHandler"
wrapper
.find("ClickHandler")
.instance()
.handleClick({
target: wrapper
.find("ClickHandler")
.getDOMNode()
.getElementsByClassName("instruction")[0]
});
expect(wrapper.find("ClickHandler").state("isVisible")).toBeTruthy();
expect(wrapper.find("h2.message").text()).toEqual("Hello World!");
});
it("hides the message when the click is outside of the box", () => {
// manually triggering the handleClick class property with a
// node outside of "ClickHandler"
wrapper
.find("ClickHandler")
.instance()
.handleClick({
target: wrapper.find("div.outside").getDOMNode()
});
expect(wrapper.find("ClickHandler").state("isVisible")).toBeFalsy();
expect(wrapper.find("h2.message").text()).toEqual("");
});
});
Опция 3
компонентов / ClickHandler / __ tests __ / ClickHandler.test.js (манипулировать состоянием)
import React from "react";
import { mount } from "enzyme";
import ClickHandler from "../index";
const initialState = {
isVisible: false
};
describe("Click Handler", () => {
let wrapper;
beforeAll(() => {
wrapper = mount(<ClickHandler />);
wrapper.setState({ ...initialState });
});
afterAll(() => {
wrapper.unmount();
});
it("renders without errors and the message should be hidden", () => {
expect(wrapper.find("div.wrapper")).toHaveLength(1);
expect(wrapper.find("h2.message").text()).toEqual("");
});
it("displays a message when a click is inside of the box", () => {
// manually manipulating state
wrapper.setState({ isVisible: true });
expect(wrapper.find("h2.message").text()).toEqual("Hello World!");
});
it("hides the message when the click is outside of the box", () => {
// manually manipulating state
wrapper.setState({ isVisible: false });
expect(wrapper.find("h2.message").text()).toEqual("");
});
});