turnerd18
turnerd18

Reputation: 303

Sinon stubs not "called" after first test

I am trying to write some basic tests for my socket.io server, but I am having trouble getting my tests to run together. For some reason, my stubs are called in the first test, but not in the following tests that check different stubs/spies. If you change the order the tests are defined in the test file, whichever one is first passes.

Here is my simplified module being tested (server.js):

var exports = module.exports = {},
    io = require('socket.io')(8080);

function startServer() {
    io.on('connection', function (socket) {
        socket.emit('loading');
    });
};

exports.startServer = startServer;

and here is my test file:

var expect = require('chai').expect,
    sinon = require('sinon'),
    mockery = require('mockery');

describe('bidding-war-server', function () {
    var biddingWarServer,
        stubbedIo;

    before(function () {
        mockery.enable();
    });

    beforeEach(function () {
        stubbedIo = {
            on: function() { }
        };
        var mockSocketIo = function (port) {
            return stubbedIo;
        };

        mockery.deregisterAll();
        mockery.registerAllowable('./server');
        mockery.registerMock('socket.io', mockSocketIo);
        biddingWarServer = require('./server');
    });

    after(function () {
        mockery.deregisterAll();
        mockery.disable();
    });

    it('should call socket.emit loading', function () {
        var stubbedSocket = {
            emit: sinon.spy(),
        };
        stubbedIo.on = sinon.stub().callsArgWith(1, stubbedSocket);

        biddingWarServer.startServer();

        expect(stubbedSocket.emit.called).to.be.true;
    });

    it('should setup io.on connection', function () {
        stubbedIo.on = sinon.spy();

        biddingWarServer.startServer();

        expect(stubbedIo.on.called).to.be.true;
    });
});

Does anyone see what I am missing here?

Upvotes: 1

Views: 734

Answers (1)

Sergey Lapin
Sergey Lapin

Reputation: 2693

This issue origins from module caching - your server.js is loaded only once.

To resolve this, I eventually came to executing mockery.enable and mockery.disable in beforeEach and afterEach blocks respectively, also forcing mockery to use clean cache.

Please have a look at updated test file:

var expect = require('chai').expect,
    sinon = require('sinon'),
    mockery = require('mockery');

describe('bidding-war-server', function () {
    var biddingWarServer,
        stubbedIo;

    beforeEach(function () {
        stubbedIo = {
            on: function() { }
        };
        var mockSocketIo = function (port) {
            return stubbedIo;
        };

        mockery.registerAllowable('./server');
        mockery.registerMock('socket.io', mockSocketIo);
        mockery.enable({useCleanCache: true});

        biddingWarServer = require('./server');
    });

    afterEach(function() {
        mockery.deregisterAll();
        mockery.disable();
    });

    it('should call socket.emit loading', function () {
        var stubbedSocket = {
            emit: sinon.spy(),
        };
        stubbedIo.on = sinon.stub().callsArgWith(1, stubbedSocket);

        biddingWarServer.startServer();

        expect(stubbedSocket.emit.called).to.be.true;
    });

    it('should setup io.on connection', function () {
        stubbedIo.on = sinon.spy();

        biddingWarServer.startServer();

        expect(stubbedIo.on.called).to.be.true;
    });
});

Upvotes: 1

Related Questions