我编写了一个直接操作 DOM 的小型库,使用 window
和 document
来搜索和更改 DOM。现在我正在尝试找出如何测试它。
到目前为止,我已经尝试过 jest 的组合+ jsdom :
const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const dom = new JSDOM('<!DOCTYPE html><p>Hello world</p>');
// these two lines do not seem to do anything useful:
global.window = dom.window;
global.document = dom.window.document;
test('can globally access and search the DOM', () => {
// this doesn't work
expect(global.document.querySelectorAll('p').length).toBe(1);
});
我在这里做错了什么,还是我的测试方法完全错误?如果是这样,进行此类测试的正确方法是什么?
在所谓的 e2e 测试和单元测试之间,我感到有点迷失,因为就我而言,这似乎介于两者之间。
理想情况下,我希望最终对多个浏览器进行测试,并获得某种测试覆盖率。但这更像是下一步。现在我根本无法让它工作。
我知道网络世界的发展速度有多快,因此,如果我完全错了,如果您能指出今天正确的做法,我将不胜感激。
更新
在 @duxfox 的一些建议之后,这是我的完整代码,因为通过这种方法,我的库现在缺少应该触发其 DOM 处理的事件 DOMContentLoaded
。
const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const { document } = (new JSDOM('<!DOCTYPE html><p>Hello world</p>')).window;
global.document = document;
global.window = document.defaultView;
window.console = global.console;
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
global[property] = document.defaultView[property];
}
});
global.navigator = {
userAgent: 'node.js'
};
// Here I'm trying to follow a suggestion from Luis:
// https://stackoverflow.com/questions/36803733/jsdom-dispatchevent-addeventlistener-doesnt-seem-to-work
window.addEventListener('DOMContentLoaded', function (ev) {
console.log('DOMContentLoaded called!'); // this is not called.
/*
console.log('window click', ev.target.constructor.name,
ev.currentTarget.constructor.name);*/
});
// loading my library here:
// const root = require('../src');
test('something', () => {
// This now works, but my library is missing
// event DOMContentLoaded to start processing the DOM
expect(document.querySelectorAll('p').length).toBe(1);
});
最佳答案
下面是我与 mocha/chai/jsdom/enzyme
一起使用的 jsdom 设置脚本
看起来 global.window
应该设置为
dom.window.document.defaultView
而不是
dom.window
完整脚本,添加其他全局属性:
var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { document } = (new JSDOM('')).window;
global.document = document;
global.window = document.defaultView;
window.console = global.console;
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
global[property] = document.defaultView[property];
}
});
global.navigator = {
userAgent: 'node.js'
};
关于javascript - 测试直接更改 DOM 的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51540912/