对 Nodejs 中发出的事件进行单元测试的最佳方法是什么?

新手上路,请多包涵

我正在编写一堆 mocha 测试,我想测试是否发出了特定事件。目前,我正在这样做:

   it('should emit an some_event', function(done){
    myObj.on('some_event',function(){
      assert(true);
      done();
    });
  });

但是,如果事件从未发出,它会使测试套件崩溃,而不是使该测试失败。

测试这个的最佳方法是什么?

原文由 manalang 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 239
2 个回答

如果您可以保证事件应在一定时间内触发,则只需设置超时即可。

 it('should emit an some_event', function(done){
  this.timeout(1000); //timeout with an error if done() isn't called within one second

  myObj.on('some_event',function(){
    // perform any other assertions you want here
    done();
  });

  // execute some code which should trigger 'some_event' on myObj
});

如果您不能保证事件何时触发,那么它可能不是单元测试的理想选择。

原文由 Bret Copeland 发布,翻译遵循 CC BY-SA 3.0 许可协议

编辑 9 月 30 日:

我看到我的答案被接受为正确答案,但 Bret Copeland 的技术(见下面的答案)更好,因为它在测试成功时更快,大多数情况下您将测试作为测试套件的一部分运行.


Bret Copeland 的技术是正确的。你也可以做一些不同的事情:

   it('should emit an some_event', function(done){
    var eventFired = false
    setTimeout(function () {
      assert(eventFired, 'Event did not fire in 1000 ms.');
      done();
    }, 1000); //timeout with an error in one second
    myObj.on('some_event',function(){
      eventFired = true
    });
    // do something that should trigger the event
  });

这可以在 Sinon.js 的帮助下缩短一点。

   it('should emit an some_event', function(done){
    var eventSpy = sinon.spy()
    setTimeout(function () {
      assert(eventSpy.called, 'Event did not fire in 1000ms.');
      assert(eventSpy.calledOnce, 'Event fired more than once');
      done();
    }, 1000); //timeout with an error in one second
    myObj.on('some_event',eventSpy);
    // do something that should trigger the event
  });

在这里,我们不仅要检查是否触发了事件,还要检查事件是否在超时期间仅触发了一次。

Sinon 还支持 calledWithcalledOn ,以检查使用了哪些参数和函数上下文。

请注意,如果您希望事件与触发事件的操作同步触发(两者之间没有异步调用),那么您可以将超时设置为零。仅当您执行需要很长时间才能完成的异步调用时,才需要 1000 毫秒的超时。很可能不是这样。

实际上,当保证事件与引起它的操作同步触发时,您可以将代码简化为

  it('should emit an some_event', function() {
    eventSpy = sinon.spy()
    myObj.on('some_event',eventSpy);
    // do something that should trigger the event
    assert(eventSpy.called, 'Event did not fire.');
    assert(eventSpy.calledOnce, 'Event fired more than once');
  });

否则,Bret Copeland 的技术在“成功”情况下(希望是常见情况)总是更快,因为它能够立即调用 done 如果事件被触发。

原文由 Myrne Stol 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题