Javascript 模拟点击文档ReactJS/JSDom
因此,我正在为在文档上添加单击事件的代码编写一些测试。我正在使用JSDom、ReactJS和Mocha/Chai设置。我在测试中尝试了以下代码:Javascript 模拟点击文档ReactJS/JSDom,javascript,unit-testing,reactjs,jsdom,Javascript,Unit Testing,Reactjs,Jsdom,因此,我正在为在文档上添加单击事件的代码编写一些测试。我正在使用JSDom、ReactJS和Mocha/Chai设置。我在测试中尝试了以下代码: document.addEventListener('click', function() { console.log('test'); }); React.addons.TestUtils.Simulate.click(document); //also tried React.addons.TestUtils.Simulate.click(do
document.addEventListener('click', function() {
console.log('test');
});
React.addons.TestUtils.Simulate.click(document);
//also tried React.addons.TestUtils.Simulate.click(document.body);
然而,这段代码并没有产生我所期望的回声
有没有一种方法可以模拟点击、按键等。。。在带有JSDom和ReactJS的文档上
更新
对于Nick answers,我已尝试将以下代码添加到测试中:
document.body.addEventListener('click', function() {
console.log('test');
});
document.body.click();
直到我没有得到控制台日志输出。我不确定JSDom和做这类事情是否有问题
如果我不能对这段代码进行单元测试,那很好,现在已经有一些代码无法进行单元测试(需要真正的DOM才能获得宽度、高度等的代码),但我希望能够对大部分代码进行单元测试(我对使用PhantomJS进行单元测试不感兴趣)。我的集成测试将涵盖这类代码
更新2
另一件需要注意的事情是,当I
console.log(文档)时代码>我看到对象附加到单击的的\u侦听器属性,因此我知道事件正在附加,它似乎没有执行。更新:文档.body。单击将在浏览器中工作,但对于jsdom,您需要手动创建事件:
document.body.addEventListener('click', function() {
console.log('test');
});
var evt = document.createEvent("HTMLEvents");
evt.initEvent("click", false, true);
document.body.dispatchEvent(evt)
上面的代码对我来说是开玩笑的,应该也可以与“solo”jsdom一起使用
2018年秋季假日更新React.addons.TestUtils.Simulate仅适用于虚拟事件。如果要分派本机事件,可以直接使用domapi
模拟单击时,如果您有一个组件可以渲染此点:
<div>
<button onClick={alert}>click me</button>
</div>
你会得到一个带有“hello world”的警报。测试UTIL所做的一切就是创建虚拟事件,并让它在虚拟dom树中冒泡,同时调用事件处理程序。只需创建一个事件并分派它:
// 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)
Event.initEvent()
// 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除外
参考资料:
您可以使用react dom/test utils中的Simulate
函数进行模拟。单击(您的\u按钮)
下面是我正在使用的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");
});
});
从“react dom”导入react dom;
从“react dom/test utils”导入{act,Simulate};
从'chai'导入{assert};
从“./组件/文件夹”导入{Folder}
让rootContainer:any;
//定义将在测试前后运行的代码
在每个之前(()=>{
rootContainer=window.document.createElement(“div”);
window.document.body.appendChild(rootContainer);
});
之后(()=>{
window.document.body.removeChild(rootContainer);
rootContainer=null;
});
描述('文件夹',()=>{
//空文件夹
const empty_文件夹={
“名称”:“音乐”,
“项目”:[]
};
//测试文件是否自动渲染
它(“渲染应渲染文件夹”,()=>{
行动(()=>{
render(,rootContainer);
});
//获取文件夹组件的html元素
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”);
//检查文件夹名称、图标和项目数是否正确呈现
assert.equal(foldername\u span.textContent,空的\u folder.name);
assert.include(foldericon.className,“ico文件夹”);
assert.equal(folderitems_span.textContent,“(空)”);
//使用模拟功能检查单击后图标是否更改
模拟。单击(文件夹\u包装器)
assert.include(foldericon.className,“ico文件夹打开”);
});
});
您是否在实际浏览器中尝试了相同的操作?它工作了吗?是的,浏览器中的代码工作得很好谢谢,这适用于单击,但是对于我需要设置事件数据的事件(例如为keyup事件设置keyCode)呢?ready看起来我会使用CustomEvent或createEventObject,但这两种方法似乎都不受JSDom@ryanzec我得做些调查才能肯定地回答这个问题。根据您测试这些事件的频率,可能需要一套单独的phantomJS测试:|@ryanzec我不认为这完全是犹太教,但是,您可以通过在使用initEvent
分派事件实例之前,将keycode
属性附加到事件实例来模拟keycode。我认为这样做对我来说有点不常见,大多数时候,我将处理react组件上的事件,react组件已经为这些事件提供了工具。这是一种特殊情况,事件位于文档上,以便处理任何键控事件(特别是在按下escape时关闭模型窗口)。在initEvent
之前附加键控代码
/,该属性在initEvent
之前起作用。我想我会同意的。我并不是100%担心它不是真正的犹太教,因为我已经在使用jsdom,它不是真正的dom。我将要进行针对真实浏览器的集成测试,这些单元测试的设计只是为了帮助及早发现问题,这些测试将比集成测试运行得快得多。大括号不匹配是故意的吗onClick={alert)
ReferenceError:MouseEvent未定义
…JSDOM等价物是什么?我同意从何处导入类?@PabloJomer查看此安装文件:@nelsonic与上面相同
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");
});
});