模拟单击文档ReactJS/JSDom

rya*_*zec 13 javascript unit-testing jsdom reactjs

所以我正在编写一些代码测试,在文档上添加一个click事件.我正在使用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);
Run Code Online (Sandbox Code Playgroud)

但是这段代码不会产生我期待的回声.

有没有办法用JSDom和ReactJS模拟文档上的click,keyup等?

UPDATE

对Nick说,我尝试将此代码添加到测试中:

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

document.body.click();
Run Code Online (Sandbox Code Playgroud)

直到我没有得到控制台日志输出.我不确定JSDom是否存在某些问题以及做这类事情.

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

UPDATE2

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

Nic*_*lin 28

更新: 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)
Run Code Online (Sandbox Code Playgroud)

上面的代码在Jest中为我工作,也应该与"solo"jsdom合作.

2018年秋季假期更新

围绕模拟事件的工具已经变得更好了.我现在改变了我的方法,使用优秀的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()
})
Run Code Online (Sandbox Code Playgroud)

虽然我仍然相信像木偶或硒(或柏树!)这样的端到端测试提供了实际工作的最高信心,但这提供了巨大的价值而不会在手动事件创建的情况下污染测试.


Bri*_*and 6

React.addons.TestUtils.Simulate仅适用于虚拟事件.如果要分发本机事件,可以直接使用DOM api执行此操作.

模拟点击时,如果您有一个组件可以渲染:

<div>
   <button onClick={alert}>click me</button>
</div>
Run Code Online (Sandbox Code Playgroud)

你有一个<button/>名为'buttonEl'的变量的引用,并运行它:

React.addons.TestUtils.Simulate.click(buttonEl, 'hello world');
Run Code Online (Sandbox Code Playgroud)

你会收到一个警告"hello world".所有测试工具都会创建虚拟事件,让它冒泡虚拟dom树,沿途调用事件处理程序.


小智 6

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);
Run Code Online (Sandbox Code Playgroud)

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

参考: