简体   繁体   English

在jest / enzyme中,如何使用[element] .addEventListener(而不是window.addEventListener)绑定的eventListener模拟元素上的单击?

[英]In jest/enzyme, how do you simulate a click on an element with eventListener bound by [element].addEventListener (not window.addEventListener)?

In react, when you have an element with an onClick prop, it's easy to use Enzyme's .simulate("click") method to click it. 在反应中,当你有一个带有onClick道具的元素时,很容易使用Enzyme的.simulate("click")方法来点击它。 However, there's an example in my codebase where an element is referenced by React's "ref" prop, and then that element's .addEventListener is invoked to bind an event handler to it. 但是,在我的代码库中有一个例子,其中一个元素被React的“ref”prop引用,然后调用该元素的.addEventListener来将事件处理程序绑定到它。

I've provided a code example: https://codesandbox.io/s/1z4xok048j 我提供了一个代码示例: https//codesandbox.io/s/1z4xok048j

The key line is this: 关键是这样的:

if (this.refs.hey) {
  this.refs.hey.addEventListener("click", this.handleClick);
}

In the code example, the eventHandler is not bound until componentDidUpdate is run, so if you click on the "click me to increment counter" div, the child element receives new props and its componentDidUpdate triggers. 在代码示例中,在运行componentDidUpdate之前不绑定eventHandler,因此如果单击“click me to increment counter”div,子元素将接收新的props及其componentDidUpdate触发器。 Then if you click on the Child element, its eventHandler triggers as expected. 然后,如果单击Child元素,其eventHandler将按预期触发。 However, I can't reproduce this behavior in my Enzyme/Jest tests. 但是,我无法在我的Enzyme / Jest测试中重现这种行为。

I've done the obvious .simulate("click") method from Enzyme and it does not work; 我已经完成了.simulate("click")中明显的.simulate("click")方法,但它不起作用; when I change from using refs and the event listeners to using an onClick , .simulate("click") works as expected. 当我从使用refs和事件监听器更改为使用onClick.simulate("click")按预期工作。 However, removing the refs causes other bugs to surface and I haven't been able to figure out why, so I'd prefer to find out a way to simulate clicking the button. 但是,删除引用会导致其他错误浮出水面,我无法找出原因,所以我更愿意找到一种模拟单击按钮的方法。

The code for .simulate("click") actually looks for the onClick function and passes the params to it, there is no 'actual' click going on. .simulate("click")的代码实际上是查找onClick函数并将params传递给它,没有“实际”点击进行。 You might have to mock the addEventListener functions with something like 您可能必须使用类似的东西来模拟addEventListener函数

// Set-up event listener mock
const map = {};
window.addEventListener = jest.genMockFn().mockImpl((event, callback) => {
  map[event] = callback;
});

The answer is actually really simple. 答案其实很简单。 The general idea is to .find the node and get the underlying HTML DOM Node with .getDOMNode() . 一般的想法是.find节点并使用.getDOMNode()获取底层HTML DOM节点。 Once you have it, replace its .addEventListener like so: 获得后,将其替换为.addEventListener如下所示:

const map ={};
const namedByRefComponent = component.find(".some-class-name");
const namedByRefDomNode = namedByRefComponent.getDOMNode();

namedByRefDomNode.addEventListener = jest.fn().mockImplementation((event, cb) => {
    map[event] = cb;
});

after that, your DOM node's event handlers can be found in map and you can invoke them in the tests. 之后,您的DOM节点的事件处理程序可以在map找到,您可以在测试中调用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM