designsuperbuild

Unit Testing Controllers the Easy Way in Express 4

Express 4 is a great upgrade to Express (find out more about the changes in this great article) and allows us to easily modularize our routes. If we go a little bit further we can also easily test our routes without mocking out the whole of Express.

Generating the Express 4 app skeleton using the Express CLI we get this:

// file:/app.js

// require route files

var users = require('./routes/users');

//... later in app.js use the routes

app.use('/users', users);
// file:/routes/users.js

var express = require   ('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res) {
  res.send('respond with a resource');
});

module.exports = router;

This is pretty hard to unit test - we'd need to stub out the Express require call using something like proxyquire.

If we make a couple of changes we can make this much simpler. First lets move the actual router to it's own file.

// file:/routes/users/getUsers.js

function getUsers(req, res) {
  res.send('respond with a resource');
}

module.exports = getUsers;

Simple, no Express dependencies - now lets wire this into Express in our main users routes file.

// file:/routes/users.js
var express = require('express');
var router = express.Router();
var getUsers = require('./users/getUsers');

router.get('/', getUsers);

module.exports = router;

All good, now we can easily unit test this route and we'll only need to mock out it's real dependencies. Using Mocha a simple test would look something like this:

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

var getUsers = require('../../app/routes/users/getUsers');

describe("Routes", function() {
  describe("GET Users", function() {

      it("should respond", function() {
        var req,res,spy;

        req = res = {};
        spy = res.send = sinon.spy();

        getUsers(req, res);
        expect(spy.calledOnce).to.equal(true);
      });     

  });
});

Contact Us

Get in touch, we're always happy to discuss your challenges.

phone: 079 1234 2125
email: david@designsuperbuild.com