如何使用QUnit测试事件侦听器

时间:2015-07-07 05:40:30

标签: javascript events event-handling qunit

我正在使用纯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()”,但这似乎没有帮助。

事件监听器在生产页面上执行正常/正常,而不是在测试中。

关于为什么事件监听器似乎没有运行的任何想法?

2 个答案:

答案 0 :(得分:1)

在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();
   });

});

答案 1 :(得分:0)

确保您要测试的代码实际包含在您的网页中。

我一直在无头环境中运行,并没有遇到任何运行时错误(除了失败的断言)。在@Amit的帮助下(让我理解),我尝试在浏览器中运行测试,发现代码甚至没有包含在页面中。