Writing unit tests for Sails.js app using mocha

Sails.js is a wonderful node.js framework.

Writing unit tests for Sails.js using mocha is pretty easy.
On the before method of a mocha test you have to lift the sails application and on the after function you have to lower it.

var Sails = require('sails');

describe('SailsMochaTest',function() {

    before(function(done) {
        this.timeout(50000);

        Sails.lift({},
            function(err,server) {
                if(err) {
                    done(err);
                } else {
                    done(err,sails);
                }
            });
    });

    it('testmethod',function(done) {

        Sails.services.sampleService.fetchRecords()
            .then(function(results) {
                done();
            })
            .catch(function(err) {
                done(err);
            });
    });

    after(function(done) {
        Sails.lower(done);
    });
});

This works pretty good however there is a gotcha. In case you want to execute tests simultaneously, for example using the –recursive argument on mocha, you will get an exception.

Cannot load or lift an app after it has already been lowered. 
You can make a new app instance with:
var SailsApp = require('sails').Sails;
var sails = new SailsApp();

For a case like this you can follow the solution recommended and lift a new sails app.

var SailsApp = require('sails').Sails;

describe('SailsMochaTest',function() {
    
    var sails = new SailsApp();

    before(function(done) {
        sails.lift({},
            function(err,server) {
                if(err) {
                    done(err);
                } else {
                    done(err,sails);
                }
            });
    });

    it('testmethod',function(done) {

        sails.services.sampleService.fetchRecords()
            .then(function(results) {
                done();
            })
            .catch(function(err) {
                done(err);
            });
    });

    after(function(done) {
        sails.lower(done);
    });
});