Question

I've got a set of modules that run based on a global event emitter. They run based on a chronological chain of events, like so:

  1. boot.ready
  2. server created (because of boot.ready event)
  3. server configured (because of server.created event)

As such, I need to create a server-test.js that performs tests in a chronological order.

Is this possible with Mocha? Something like the following?

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

Because there seemed to be some confusion about the way this global event emitter works, this is the server/creator.js module:

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

    });
};

As you can see, the server is created after boot.ready. This fires server.created, after which the configurer will run which will then fire server.configured.

This chain of events needs to be tested by mocha.

Was it helpful?

Solution

If I'm testing a chain of events the quick way is to do it is nested eventEmitter.once calls like this:

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

edit: as pointed out server.created will be fired before the test's boot.ready handler is fired. Here's a workaround:

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

Hope this helps.

OTHER TIPS

Actually mocha use function.length to your it callbacks to know if you want them asynchronously, so with function(done) you can't known in which order they're run. function() without done argument will run them synchronously.

EDIT

Your mediator is an EventEmitter2 meaning that when you emit something, the handler will be run async. Like I said they's no way to known the order in which the are executed.

The problem is in you required modules, each event should probably be emitted in the handler of the previous. Code is better than words :

// 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

});

Also you should know that emit is immediate in node so you'd better add your listeners before emitting.

Hope this is clear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top