Unit testing Node.js Applications using Mocha

Posted by: Ravi Kiran , on 9/12/2015, in Category Node.js
Views: 15348
Abstract: Get started with unit testing Node.js applications using the Mocha Test framework and Node.js own built-in library 'assert' for assertion

Unit testing has become an integral part of daily development process. It is an important phase of software development, as it is an attempt made towards keeping the code cleaner and making the product functionally better. Applications written in Node.js are no different. They would face the similar kind of issues that any other application would face, if they are deployed without testing them enough.

 

Now some of you may have a question in your minds that what can you test in Node.js? Any server based application has business logic, data access logic and endpoints to interact with the clients. We need to test all of them as even a small change applied on any of this logic, sometimes impacts functionality of the application as a whole.

Setting up Node.js Testing Environment

Before we start writing unit tests, we need to have an environment ready to run the tests. To do so, we need to pick a test framework and set the environment for it.

We have a number of test frameworks available to test Node.js applications. One of the well-known frameworks amongst them is Mocha. It is a BDD (Behavior Driven Development) based test framework composed with a simple syntax. Like any other Node.js packages, Mocha is available on NPM. If it is installed globally, it can be used to run tests using command line from any location.

> npm install -g mocha

A Basic Node.js Application

Let’s set up a basic Node.js application to test. The application would contain one page and an API. Both of these endpoints would be created using Express. Create a new folder on your system, add a new JavaScript file to this folder and name it server.js. Place the following code in this file:

var app = require('express')();

app.get('/api/person', function (request, response) {
    response.send({
        name:"Alex",
        city:"London",
        age:25
    });
});

app.get('/', function (request, response) {
    response.sendFile(__dirname + '/index.html');
});

app.listen(3000, function () {
    cosole.log("Server started on port 3000");
});

module.exports.server = app;

To complete the sample, just install the Express package.

Note: Express.js is a light weight framework built on top of Node.js and it provides abstractions to make our job of working with HTTP easier. Express also provides a way to add middle-wares to the pipeline. These middle-wares can be used to perform tasks like authentication, logging, and any other pre or, post processing logic that has to be executed with every request.

Express.js can be installed into using NPM. Run the following command to install express.js:

> npm install express

Unit Testing Sample using Mocha

During testing, we compare the value of variables and check to see if they match the values of what we wrote in our original program. In other words, we need to verify that our code runs as expected. This is called as running an assertion. We need to use an assertion library along with Mocha to verify the correctness of our logic. The home page of the Mocha’s official site lists many assertion testing libraries like Chai, Expect and Should.js for many programming styles. Of these, we will use Node.js own built-in library assert for assertion. It can be installed using NPM.

> npm install assert --save-dev

Add a new file to the folder and name it tests.js.

To begin with, let’s write a simple function and test it using Mocha. Add the following snippet to this file:

var assert = require('assert');

describe('Sample unit tests', function () {
    function add(x, y){
        return x+y;
    }

    it('should return 5', function () {
        assert.equal(add(2,3), 5);
    });
});

To run this test, open a command prompt, move to the location of this folder and run the following command:

> mocha tests.js

The result of this command is the following:

nodejs-pass-test

Let’s make the test fail. For this, change the value compared to 6 in the above assertion and run the test using the same command. Here’s the result:

nodejs-fail-test

Now that you have some familiarity with Mocha and Assert, let’s write tests to assert the logic written in server.js file. As the logic in this file deals with HTTP requests and responses, we need a way to manually send requests and assert their responses. The package supertest provides us with a way to do this. Install it using the following NPM command:

> npm install supertest --save-dev

Let’s get a reference of the object exposed by this library and invoke the server file to start the Node.js server.

var request = require('supertest');

//inside describe block
var server;
beforeEach(function () {
  server = require('./server').server;
});

A request to home URL of the application returns an HTML file. We can assert this behavior by sending a request to the path and then check the type of response generated by the server. Following test asserts request to the home URL:

it('should respond with an htmL file when root is requested', function (done) {
  request(server)
    .get('/')
    .expect(200)
    .end(function (err, response) {
      assert.equal(response.header['content-type'], 'text/html; charset=UTF-8');
      done();
    });
});

If you observe the above test carefully, you will see that it accepts a parameter (done) in the callback function of the test. The parameter indicates that it is an asynchronous test. It is a callback function that needs to be called upon completion of the test. As the test in above case can be said to be completed after the assertion is checked, we called the done function after the assertion.

Let’s check if the REST API /api/person returns the right result using the same procedure. Following is the test case:

it('should respond with JSON data when API is called', function (done) {
  request(server)
    .get('/api/person')
    .expect(200)
    .end(function (err, response) {
      assert.equal(response.header['content-type'], 'application/json; charset=utf-8');
      assert.deepEqual(response.body, {
        name:"Alex",
        city:"London",
        age:25
      });
      done();
    });
});

A request to any path other than these two should result a 404 from the server. We can check this condition too. Following is the test for this:

it('should send 404 when a request is made to any other path', function (done) {
  request(server)
    .get('/dummy/path')
    .expect(404, done);
});

Conclusion

Unit testing provides an assurance about both code and functionality of the application. I hope this article got you started with testing Node.js. Extend your knowledge on top of it to test other pieces of the Node.js application.

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Rabi Kiran (a.k.a. Ravi Kiran) is a developer working on Microsoft Technologies at Hyderabad. These days, he is spending his time on JavaScript frameworks like AngularJS, latest updates to JavaScript in ES6 and ES7, Web Components, Node.js and also on several Microsoft technologies including ASP.NET 5, SignalR and C#. He is an active blogger, an author at SitePoint and at DotNetCurry. He is rewarded with Microsoft MVP (Visual Studio and Dev Tools) and DZone MVB awards for his contribution to the community


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook