javascript 模拟点击文档 ReactJS/JSDom

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27557624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 07:37:43  来源:igfitidea点击:

Simulating click on document ReactJS/JSDom

javascriptunit-testingreactjsjsdom

提问by ryanzec

So I am writing some tests for code that adds a click event on the document. I am using JSDom, ReactJS, and Mocha/Chai setup. I have tried the following code in a test:

所以我正在为在文档上添加点击事件的代码编写一些测试。我正在使用 JSDom、ReactJS 和 Mocha/Chai 设置。我在测试中尝试了以下代码:

document.addEventListener('click', function() {
  console.log('test');
});
React.addons.TestUtils.Simulate.click(document);
//also tried React.addons.TestUtils.Simulate.click(document.body);

however this code does not produce the echo that I am expecting.

但是这段代码不会产生我期望的回声。

Is there a way to simulate click, keyup, etc... on the document with JSDom and ReactJS?

有没有办法用 JSDom 和 ReactJS 在文档上模拟点击、按键等...?

UPDATE

更新

To Nick answers, I have tried adding this code to the test:

对于 Nick 的回答,我尝试将此代码添加到测试中:

document.body.addEventListener('click', function() {
  console.log('test');
});

document.body.click();

and I till don't get the console log output. I am not sure if there is some issue with JSDom and doing this type of thing.

我直到没有得到控制台日志输出。我不确定 JSDom 是否存在问题并执行此类操作。

If I can't unit test this code, that's fine, there is already some code that I can't unit test right now (code that requires a real DOM to be able to get widths, heights, etc...) but I would like to be able to unit test most of the code (and I am not interested in using PhantomJS for unit testing). My integration tests will cover that type of code.

如果我不能对这段代码进行单元测试,那很好,已经有一些代码我现在无法进行单元测试(需要真正的 DOM 才能获得宽度、高度等的代码......)但是我希望能够对大部分代码进行单元测试(我对使用 PhantomJS 进行单元测试不感兴趣)。我的集成测试将涵盖那种类型的代码。

UPDATE2

更新2

Another thing to note is that is that when I console.log(document);I see object attached to the _listenersproperty for clickso I know the event is being attached, it just does not seem to be executing.

另一件要注意的事情是,当我console.log(document);看到对象附加到_listeners属性时,click我知道事件正在被附加,但它似乎没有执行。

回答by Nick Tomlin

Update:document.body.clickwill work in a browser, but for jsdom you need to manually create the event:

更新:document.body.click将在浏览器中工作,但对于 jsdom,您需要手动创建事件:

document.body.addEventListener('click', function() {
  console.log('test');
});

var evt = document.createEvent("HTMLEvents");
evt.initEvent("click", false, true);
document.body.dispatchEvent(evt)

The above code is working for me in Jest and should work with "solo" jsdom as well.

上面的代码在 Jest 中对我有用,也应该与“solo”jsdom 一起使用。

Autumn 2018 holiday update

2018 年秋季假期更新

The tools around simulating events have gotten a great deal better. I've currently shifted my approach to use the excellent react-testing-libraryto render my components and dispatch events:

模拟事件的工具已经变得更好了。我目前已经改变了我的方法,使用优秀的react-testing-library来呈现我的组件和调度事件:

import {render, fireEvent} from 'react-testing-library'

test('example', () => {
  const handleClick = jest.fn()

  const {getByText} = render(<div><button onClick={handleClick}>Click Me</button></div>)
  fireEvent.click(getByText('Click Me'))

  expect(handleClick).toHaveBeenCalled()
})

While I still believe in end to end tests with something like puppeteer or selenium (or cypress!) provide the highest level of confidence that something actually works, this provides a huge amount of value without polluting tests with manual event creation.

虽然我仍然相信使用 puppeteer 或 selenium(或 cypress!)之类的端到端测试可以提供最高水平的信心,即某些东西确实有效,但这提供了巨大的价值,而不会因手动事件创建而污染测试。

回答by Brigand

React.addons.TestUtils.Simulate only works with virtual events. If you want to dispatch native events, you can do that with the DOM api directly.

React.addons.TestUtils.Simulate 仅适用于虚拟事件。如果你想调度原生事件,你可以直接使用 DOM api 来完成。

When simulating a click, if you have a component which renders this:

在模拟点击时,如果您有一个呈现此内容的组件:

<div>
   <button onClick={alert}>click me</button>
</div>

And you have a reference to the <button/>in a variable called 'buttonEl', and run this:

并且您引用了<button/>一个名为“buttonEl”的变量,然后运行:

React.addons.TestUtils.Simulate.click(buttonEl, 'hello world');

You'd get an alert with 'hello world' in it. All test utils does is create the virtual event, and let it bubble up the virtual dom tree, calling the event handlers along the way.

你会收到一个带有“hello world”的警报。所有测试工具所做的就是创建虚拟事件,并让它在虚拟 dom 树中冒泡,并在此过程中调用事件处理程序。

回答by Wayne

Event.initEvent()is deprecated and the Event()constructor should now be used instead.

Event.initEvent()已弃用,Event()现在应改用构造函数。

// Add a click event listener to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a click event with optional event initialisers: bubbles, cancelable and composed
var evt = new Event('click', { bubbles: false, cancelable: false, composed: false });

// Event can then be dispatched against any element, not only the document
document.dispatchEvent(evt);
myDiv.dispatchEvent(evt);

Browser support is good with the exception of Internet Explorer.

浏览器支持良好,但 Internet Explorer 除外。

References:

参考:

回答by Riccardo Bartoli

Simply create an Eventand dispatch it:

只需创建一个Event并发送它:

// Add an event listeners to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a new `click` event and `dispatch` it
var event = new MouseEvent('click')
document.dispatchEvent(event)