Testing Mean.js Controllers – Part 1

It’s time to test controllers. In this post, I’ll test a controller that returns a json response.

Step 1 is to install node-mocks-http.

Step 2 is to download jsdValidator.

In our sample controller test file, include jsdValidator and create a schema. The schema will match what should get returned by the real controller.

The relevant portion of our route looks like this:

var taskJobs = require('app/controllers/taskJobs.server.controller');
app.route('/taskJobs')
   .get(taskJobs.list);

In our taskJobs.server.controller, we have:

exports.list = function (req, res) {
 if (!users.isAuthorized(req, ['user'])) {
 res.redirect('/');
 return;
 }
 var restJobs = restValidatorService.restJobs;
 var scre = /^(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)/;
 var cronX;
 var output = [];
 _.forEach(taskJobs, function (job) {
 output.push({
 task: job.task.service,
 enabled: job.enabled,
 persist: job.persist,
 status: job.running ? 'running' : 'waiting',
 lastRun: job.startTimeStamp,
 processedMessages: job.processedMessages,
 errorMessages: job.errorMessages,
 commError: job.commError
 });
 });
 res.jsonp(output);
};

The controller is working if it responds with json output in a particular format. So, include jsdValidator in the controller test file, and create a schema that matches what the controller is supposed to produce. See jsdValidator for more info on how it works and how to build schemas.

The relevant portion of taskJobs.server.controller.test.js looks like this:

var jsd = require('app/services/jsdValidator/jsdValidator');
var streamSchema = {
	'Type': 'Array',
	'Optional': false,
	'Values': [
    {
      'Type': 'Object',
      'Optional': false,
      'Attributes': [
        {
          'Name': 'task',
          'Description': '',
          'Type': 'String',
          'Optional': false
        },{
          'Name': 'enabled',
          'Description': '',
          'Type': 'Boolean',
          'Optional': false
        },{
          'Name': 'persist',
          'Description': '',
          'Type': 'Boolean',
          'Optional': false
        },{
          'Name': 'status',
          'Description': '',
          'Type': 'String',
          'Values': ['running','waiting'],
          'Optional': false,
        },{
          'Name': 'lastRun',
          'Description': '',
          'Type': 'String',
          'Optional': false,
          'CanBeNull': true
        },{
          'Name': 'processedMessages',
          'Description': '',
          'Type': 'Number',
          'Optional': false
        },{
          'Name': 'errorMessages',
          'Description': '',
          'Type': 'Number',
          'Optional': false
        },{
          'Name': 'commError',
          'Description': '',
          'Type': 'Number',
          'Optional': false,
          'CanBeNull': true
        }
      ]
    }
  ]
};
describe('myTasks.Server.Controller.Test - Show Tasks', function() {
 it('should return a list of tasks', function(done) {
    var response = buildResponse();
    var request = http_mocks.createRequest({
       method: 'GET',
       url: '/myTasks'
    });
    response.on('end', function() {
       if (response.statusCode !== 200) {
          done(new Error('Incorrect Status Code: ' + response.statusCode));
       } else {
          jsdv = new JSDValidator({Schema: myTaskSchema});
          var isValidated = jsdv.Validate(JSON.parse(response._getData()));
          if (!isValidated) {
             done(new Error('Invalid Response: ' + jsdv.Error));
          } else {
             done();
          }
      }
    });
    controller.list(request, response);
 });
})

In the test controller, set up a few parameters:
First, the url needs to match the url in the route file for the action in the controller that you want to test.
Second, at the bottom, where it says: controller.list(request, response), .list is the actual method that you want to test in the controller. It has to match the method that is in the route file.
Third, modify the ‘describe’ and ‘it’ descriptions, and you’re done. It’s pretty easy to clone this code to test all of your controllers.

Advertisements

About jeffmershon

Director of Program Management at SiriusXM.
This entry was posted in Software and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s