On my previous article get your SailsJS testing environment setup, and also how to run a basic test. But let’s face it: when it comes to real life, *basic is never enough! On this article I will be covering a more realistic scenario:
Let’s suppose you wrote a SailsJS Controller and a SailsJS Service. You got them to work together, and now you want to mock the service while testing your controller.
The problem is that SailsJS magically injects Services — and Models, and everything else — into the Controller, making it difficult to simply call HelloController.index()
without lifting SailsJS. We need the dependencies to be in place (otherwise we will get a bunch of ugly undefined is not a function kind of errors.
Fortunately, lifting SailsJS in code is almost as easy as running sails lift
on your command line, and that is exactly what we are going to do in order run our tests.
I’m glad you asked! First things first, pretend we already have a controller and a service in place: The controller is called TestingServicesController
and the service is called MyFirstService
.
Step 1: Start by instantiating SailsJS in your test file:
var Sails = require('sails'),
sinon = require('sinon'),
assert = require('assert');
Step 2: Lift SailsJS before executing each test and lower it after the test is executed:
var app,
testingServicesController;
// Gets run before each test
before(function beforeControllerTest(done) {
// Lift Sails and start the server
Sails.lift({
log: {
level: 'error'
},
}, function(err, sails) {
// Instantiates new sails application
app = sails;
// Instantiates controller
testingServicesController = app.controllers.testingservices;
// Lets testing framework know async call is done
done(err, sails);
});
});
// Gets run after each test
after(function afterControllerTest(done){
// Destroys application
app.lower(done);
});
Step 3: Mock service and test controller
it('should have called mocked service', function() {
// Mocking our service
sinon.stub(app.services.myfirstservice, 'sayHello', function() {
return 'Hello I am the mocked Service';
});
// JSON object spy
var send = sinon.spy();
// Executes controller action
testingServicesController.index(null, {
'send': send
});
// Makes sure the mocked service was called
// instead of the real one
assert(send.called);
assert(send.calledWith('Our service has a message for you: Hello I am the mocked Service'));
// Restores our mock to the original service
app.services.myfirstservice.sayHello.restore();
// Notice that the above action this is very important
// because if the original action does not get restored,
// then this mock will be used in other tests
});
Below is what my code looks like when we put all three steps together:
var Sails = require('sails'),
sinon = require('sinon'),
assert = require('assert');
describe('The TestingServices Controller', function() {
// app and testingServicesController
var app,
testingServicesController;
// Global before hook
before(function beforeControllerTest(done) {
// Lift Sails and start the server
Sails.lift({
log: {
level: 'error'
},
}, function(err, sails) {
app = sails;
// TestingServices controller
testingServicesController = app.controllers.testingservices;
done(err, sails);
});
});
after(function afterControllerTest(done){
app.lower(done);
});
describe('when we invoke the index action', function() {
before(function() {
// Mocking our service
sinon.stub(app.services.myfirstservice, 'sayHello', function() {
return 'Hello I am the mocked Service';
});
});
after(function() {
// Restores our mock to the original service
app.services.myfirstservice.sayHello.restore();
});
it('should have called mocked service', function() {
// JSON object spy
var send = sinon.spy();
// Executes controller action
testingServicesController.index(null, {
'send': send
});
// Makes sure the mocked service was called
// instead of the real one
assert(send.called);
assert(send.calledWith('Our service has a message for you: Hello I am the mocked Service'));
});
});
});
You know you can always count on me when it comes to post my working code to GitHub! Check out the full working copy here:
https://github.com/sergiocruz/sails-unit-test
Copyright © 2022 Sergio Cruz. All rights reserved.