我使用纯Javascript(没有JQuery(,并试图让QUnit测试我的函数,该函数只能通过事件调用,即它是一个事件侦听器。
所以我想测试的功能是:
(function() {
function the_one_i_want_to_test() {
// do stuff
}
window.addEventListener('load', function() {
var some_element = ...;
some_element.addEventListener('click', the_one_i_want_to_test);
});
})();
我知道我可以公开这个函数来测试它,但它只被用作事件侦听器,我不想污染全局命名空间。
这就是为什么我试图通过手动触发"点击"事件,然后检查所需效果(在我的测试中(,一举两得。
问题是,事件处理程序似乎根本没有执行,要么是因为QUnit在执行效果检查之前没有等待它,要么是其他原因。
所以我的QUnit测试代码是这样的:
QUnit.test('test function', function(assert) {
var some_element = ...;
var event = document.createEvent('Event');
event.initEvent('click', true, true);
some_element.dispatchEvent(event);
assert.ok(...assert one or more effects of running "the_one_i_want_to_test"...);
});
我尝试过将JQuery包括在内,只是为了让测试使用".trigger((",但这似乎没有帮助。
事件侦听器在生产页面上执行良好/正常,只是在测试中没有执行。
关于为什么事件监听器似乎没有运行,有什么想法吗?
在Javascript中,当引发事件时,不会立即执行事件处理程序。它们在列表中排队,并在当前代码块完成后执行。到那时,测试已经结束。
您必须使用setTimeout技巧来排队验证代码,以便它在处理程序之后执行。当延迟为0(或未指定(时,代码将尽快排队等待执行,这意味着在事件处理程序有机会运行之后。
正如Amit所说,您还需要使用assert.async()
方法来获得一个done()
函数,该函数将在断言后调用。这使得QUnit.test
等待您调用它,然后再进行下一个测试。
试试这样的东西:
QUnit.test('test function', function(assert) {
var some_element = ...;
var event = document.createEvent('Event');
event.initEvent('click', true, true);
some_element.dispatchEvent(event);
var done = assert.async();
setTimeout(function() {
assert.ok(...assert one or more effects of running "the_one_i_want_to_test"...);
done();
});
});
确保您想要测试的代码实际上包含在您的网页中。
我一直在无头环境中运行,没有得到任何运行时错误(除了失败的断言(。在@Amit的帮助下(让我清醒过来(,我尝试在浏览器中运行测试,发现代码甚至没有包含在页面中。