如何按时间顺序运行摩卡测试?

时间:2012-05-10 18:38:14

标签: javascript unit-testing node.js asynchronous mocha

我有一组基于全局事件发射器运行的模块。它们基于按时间顺序排列的事件链运行,如下所示:

  1. boot.ready
  2. 服务器创建(因为boot.ready事件)
  3. 配置的服务器(由于server.created事件)
  4. 因此,我需要创建一个按时间顺序执行测试的server-test.js。

    Mocha可以实现吗?像下面这样的东西?

    var EventEmitter2      = require('eventemitter2').EventEmitter2,
        should             = require('should');
    
    describe('server', function() {
    
        var mediator = new EventEmitter2({
                wildcard: false
            });
    
        require('../../src/routines/server/creator')(mediator);
        require('../../src/routines/server/configurer')(mediator);
    
        it('should be created after boot', function(done) {
            mediator.once('server.created', function(server) {
                server.should.exist;
                done();
            });
    
            it('should be configured after created', function(done) {
                mediator.once('server.configured', function() {
                    done();
                });
            });
    
            mediator.emit('boot.ready');
        });
    });
    

    因为这个全局事件发射器的工作方式似乎有些混乱,所以这是server/creator.js模块:

    module.exports = function(mediator) {
    
        var express = require('express');
    
        mediator.once('boot.ready', function() {
    
            var server = express.createServer();
    
            //event: server created
            mediator.emit('server.created', server);
    
        });
    };
    

    如您所见,服务器是在boot.ready之后创建的。这将触发server.created,之后将运行配置程序,然后将触发server.configured

    这一系列事件需要通过摩卡进行测试。

2 个答案:

答案 0 :(得分:2)

如果我正在测试一系列事件,那么快速的方法是嵌套的eventEmitter.once调用如下:

it('executes in the right sequence', function(done) {
  mediator.once('boot.ready', function() {
    mediator.once('server.created', function() {
      done()
    })
  })
})

编辑:正如所指出的那样,server.created将在测试的boot.ready处理程序被触发之前被触发。这是一个解决方法:

it('executes in the right sequence', function(done) {
  var bootReadyFired = false
  mediator.once('boot.ready', function() {
    bootReadyFired = true
  })
  mediator.once('server.created', function() {
    assert.ok(bootReadyFired)
    done()
  })
})

希望这有帮助。

答案 1 :(得分:0)

实际上,mocha使用function.length到您的it回调来知道您是否想要它们是异步的,因此使用function(done)您无法知道它们的运行顺序。没有完成参数的function()将同步运行它们。

修改

你的mediator是一个EventEmitter2,这意味着当你发出一些东西时,处理程序将运行异步。就像我说的那样,他们无法知道执行顺序。

问题出在你所需的模块中,每个事件都应该在前面的处理程序中发出。代码优于单词:

// require('../../src/routines/server/creator')(mediator);
// I guess this module creates the server, then it should emit server.created

// require('../../src/routines/server/configurer')(mediator)
// This one should listen to server.created then configure the server
// and finally emit server.configured
// So in it you should have something like this:

mediator.once('server.created', function(server) {

    // Here you should configure you're server
    // Once it is configured then you emit server.configured

});

此外,您应该知道节点中的发射是立即的,因此您最好在发射之前添加侦听器。

希望这很清楚。