所以我正在编写一些代码,用于在文档上添加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);
但是这段代码不会产生我期待的回声。
有没有办法用JSDom和ReactJS模拟文档上的click,keyup等?
更新
对尼克回答,我尝试将此代码添加到测试中:
document.body.addEventListener('click', function() {
console.log('test');
});
document.body.click();
我直到没有得到控制台日志输出。我不确定JSDom是否存在某些问题以及做这类事情。
如果我无法对这段代码进行单元测试,那很好,已经有一些我现在无法进行单元测试的代码(代码需要一个真正的DOM才能获得宽度,高度等等...... )但我希望能够对大部分代码进行单元测试(我对使用PhantomJS进行单元测试不感兴趣)。我的集成测试将涵盖这种类型的代码。
UPDATE2
需要注意的另一件事是,当我console.log(document);
时,我看到对象附加到_listeners
的{{1}}属性,所以我知道事件是附加的,它似乎不是正在执行。
答案 0 :(得分:27)
更新: 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)
以上代码在Jest中为我工作,也应该与“solo”jsdom合作。
围绕模拟事件的工具已经变得更好了。我目前已经改变了方法,使用优秀的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()
})
虽然我仍然相信使用像puppeteer或selenium(或cypress!)这样的端到端测试,但它可以提供最高级别的信任,实际上可以正常工作,这可以提供巨大的价值,而不会通过手动事件创建来污染测试。 / p>
答案 1 :(得分:6)
React.addons.TestUtils.Simulate仅适用于虚拟事件。如果要分发本机事件,可以直接使用DOM api执行此操作。
模拟点击时,如果你有一个组件可以渲染:
<div>
<button onClick={alert}>click me</button>
</div>
您可以在名为&#39; buttonEl&#39;的变量中引用<button/>
,然后运行:
React.addons.TestUtils.Simulate.click(buttonEl, 'hello world');
您可以通过“hello world&#39;在里面。所有测试工具都会创建虚拟事件,让它冒泡虚拟dom树,沿途调用事件处理程序。
答案 2 :(得分:1)
您可以使用 Simulate
=> react-dom/test-utils
中的 Simulate.click(your_button)
函数
这是我使用的示例 mocha
、chai
和 jsdom
import ReactDOM from "react-dom";
import {act, Simulate} from "react-dom/test-utils";
import {assert} from 'chai';
import {Folder} from "../components/Folder"
let rootContainer:any;
// Define the code that will run before and after the test
beforeEach(() => {
rootContainer = window.document.createElement("div");
window.document.body.appendChild(rootContainer);
});
afterEach(() => {
window.document.body.removeChild(rootContainer);
rootContainer = null;
});
describe('Folder', ()=>{
// an empty folder
const empty_folder = {
"name": "Music",
"items": []
};
// test that the file render automatically
it("Renders should render a Folder", () => {
act(() => {
ReactDOM.render(<Folder folder_obj={empty_folder} level = {0}/> , rootContainer);
});
// Get the html elements of Folder components
const folder_wrapper = rootContainer.querySelector(".wrapper");
const foldername_span = rootContainer.querySelector(".left-part span:last-child");
const foldericon = rootContainer.querySelector(".left-part span:first-child i");
const folderitems_span = rootContainer.querySelector(".right-part span");
// Check if the folder name, icons, number of items are rendred correctly
assert.equal(foldername_span.textContent, empty_folder.name);
assert.include(foldericon.className, "ico-folder");
assert.equal(folderitems_span.textContent, "(empty)");
// Check that the icon is changed after a click using Simulate function
Simulate.click(folder_wrapper)
assert.include(foldericon.className, "ico-folder-open");
});
});
答案 3 :(得分:0)
只需创建一个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)
答案 4 :(得分:0)
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);
除Internet Explorer之外,浏览器支持都很好。
参考文献: