简体   繁体   English

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

[英]How to test event listeners using QUnit

I'm using pure Javascript (no JQuery) and I'm trying to get QUnit to test my function that is only invoked via an event, ie it's an event listener. 我正在使用纯Javascript(没有JQuery),并且试图让QUnit测试仅通过事件调用的函数,即它是一个事件侦听器。

So the function I wish to test is of the form: 因此,我要测试的功能具有以下形式:

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

I know I could expose the function to test it, but it is only ever used as an event listener and I don't want to pollute the global namespace. 我知道我可以公开该功能以对其进行测试,但是它仅用作事件监听器,并且我不想污染全局名称空间。

That's why I am trying to kill two birds with one stone by manually triggering a "click" event and then checking for desired effects (in my tests). 这就是为什么我试图通过手动触发“喀哒”事件然后检查所需的效果(在我的测试中)用一块石头杀死两只鸟。

The problem is that the event handler doesn't seem to be executing at all, either because QUnit doesn't wait for it before performing the effects checks, or for some other reason. 问题在于事件处理程序似乎根本没有执行,这是因为QUnit在执行效果检查之前没有等待它,或者是由于其他原因。

So my QUnit test code looks like this: 所以我的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"...);
});

I have tried including JQuery just for the tests to use ".trigger()", but that doesn't seem to help. 我尝试包括JQuery只是为了使测试使用“ .trigger()”,但这似乎无济于事。

The event listener executes fine/normally on the production page, just not in the tests. 事件侦听器可以在生产页面上正常执行,而不是在测试中正常执行。

Any ideas on why the event listener doesn't seem to be running? 关于为何事件监听器似乎没有运行的任何想法?

In Javascript, event handlers are not executed immediately when the event is raised. 在Javascript中,引发事件时不会立即执行事件处理程序。 They are queued up on a list, and execute after the current code block is done. 它们在列表上排队,并在当前代码块完成后执行。 By that time, the test is over. 到那时,测试已经结束。

You have to use the setTimeout trick to queue up your validation code so that it executes after the handler. 您必须使用setTimeout技巧将验证代码排队,以便其在处理程序之后执行。 When the delay is 0 (or unspecified), the code will be queued for execution as soon as possible, meaning right after the event handler gets a chance to run. 当延迟为0(或未指定)时,代码将尽快排队等待执行,这意味着事件处理程序有机会运行之后。

As Amit says, you also need to use the assert.async() method to get a done() function that you'll call after your assertions. 正如阿米特所说,您还需要使用assert.async()方法来获取一个done()函数,该函数将在断言之后调用。 This makes QUnit.test wait until you invoke it before moving on to the next test. 这使QUnit.test一直等到您调用它,然后才能进行下一个测试。

Try something like this: 尝试这样的事情:

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

});

Ensure that the code you wish to test is actually included in your web page. 确保您要测试的代码实际上包含在您的网页中。

I have been running in a headless environment and didn't get any runtime errors (apart from the failed assertions). 我一直在无头的环境中运行,没有遇到任何运行时错误(除了失败的断言)。 With the help of @Amit (to bring me to my senses), I tried running the tests in a browser and discovered the code was not even being included in the page. 在@Amit的帮助下(使我感动),我尝试在浏览器中运行测试,发现该代码甚至没有包含在页面中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM