Introduction To Mocha [Part-1]

23 / May / 2015 by Deepak Vishwakarma 0 comments

 

Introduction To Mocha

Recently I have started learning MochaJs for unit testing of my NodeJs application. Although  http://mochajs.org/ is very well documented and refine in its own. But that is most respect to Mocha itself. I tried and created lots of example so that it can relate to NodeJs.

Before starting further, Clone/download examples from git repository- Introduction To Mocha

Table of Contents

Introduction To MochaJs

Mocha is a JavaScript testing framework, which runs on NodeJs and browser. It is mostly use to test synchronous and asynchronous JavaScript code. Easy to use and it’s also provides you simple test case results.

  • Installation

This library is available on npm. Install with npm:

  • NPM Install(npm)


$ npm install -g mocha

Above command will install mocha globally to your npm environment.

  • Starting with mocha

When you work on TDD(Test Driven Development), You need to take care of your project structure. Where you will put your test cases on all. I have basically created a test folder where i put all test cases.


$ mkdir test

Once you create a testing folder, Just create your first mocha test case. ie. testing.js It would be something like


//1-start-with-mocha.js
var assert = require("assert")
describe('String', function () {
    describe('#substring()', function () {
        it('should return -1 when the value is not present', function () {
            assert.equal(-1, 'True Developer!! Testing is hardest thing to do...'.indexOf('developer'));
        });
    });
});

Output would be: String #substring() ✓ should return -1 when the value is not present

Explanation of Previous Code

describe is use to describe different level of block of your code. it is to specify the test case that you have created.

  • Introduction to Assertion

Mocha is very flexible to use any of the assertion library. If it throws error it will work with mocha. There are lots of assertion library available in cloud. I personally prefer shouldjs and chaijs. You can use native assertion module of node.

  • Using NodeJs assert Module


var assert = require("assert");
describe('String', function () {
    describe('#substring()', function () {
        it('should return -1 when the value is not present', function () {
            assert.equal(-1, 'True Developer!! Testing is hardest thing to do...'.indexOf('developer'));
        });
    });
});

  • Using ShouldJs


$  npm install should --save-dev


//2-starting-to-shouldjs.js
var should = require('should')
describe('Array', function () {
    describe('#indexOf()', function () {
        it('should return -1 when the value is not present', function () {
            [1, 2, 3].indexOf(5).should.equal(-1);
            [1, 2, 3].indexOf(0).should.equal(-1);
        })
    })
})
    
  • Synchronous code Testing

By default javascript environment is sync in nature(Not nodejs ;) ). When you don’t callback to test cases, Mocha runs all test cases serially and sequentially.


//3-synchronous-testing.js
var should = require('should')
describe('Array', function () {
    describe('#indexOf()', function () {
        it('Test Case-1: should return -1 when the value is not present', function () {
            [1, 2, 3].indexOf(5).should.equal(-1);
            [1, 2, 3].indexOf(0).should.equal(-1);
        });
    });
});
describe('String', function () {
    describe('#substring()', function () {
        it('Test Case-2: should return -1 when the value is not present', function () {
            'True Developer!! Testing is hardest thing to do...'.indexOf('developer').should.equal(-1);
        });
    });
});

  • Asynchronous code Testing

Development environment like nodejs, is async in nature. Mocha provides you such design pattern where you can define callback function. Call it when you done with it.


//4-asynchronous-testing.js
var should = require('should')
describe('Array', function () {
    describe('#indexOf()', function () {
        it('Test Case-1: should return -1 when the value is not present', function (done) {
            setTimeout(function () {
                [1, 2, 3].indexOf(5).should.equal(-1);
                [1, 2, 3].indexOf(0).should.equal(-1);
                done();
            }, 1000)
        });
    });
});
describe('String', function () {
    describe('#substring()', function () {
        it('Test Case-2: should return -1 when the value is not present', function (done) {
            setTimeout(function () {
                'True Developer!! Testing is hardest thing to do...'.indexOf('developer').should.equal(-1);
                done();
            }, 500);
        });
    });
});

  • Testing With Nodejs

In nodejs you mostly deals with async libraries. To show how to use mocha on node, I have created a dummy crud operation on mogoDb using mongoose.js.


//5-testing-with-nodejs.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = require('../db/cat');
describe('Cat Modal', function () {
    describe('#create()', function () {
        it('should return cat when cat has created', function (done) {
            Cat.find({}).remove(function () {
                var cat = new Cat({name: 'Deepak'});
                cat.save(function (error, cat) {
                    console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
                    console.log('%j', cat);
                    console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
                    done();
                })
            });
        });
    });
});

  • Error Handling With Mocha

The real purpose of testing is to write test cases which can be use in future in case of any modification of the Api without understanding the logic behind it. Here i have given small demonstration how we can handles error in api


//6-error-handling-with-mocha.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = require('../db/cat');
describe('Cat Modal', function () {
    describe('#create()', function () {
        it('should fail since cat is already created with name Billi', function (done) {
            var cat = new Cat({name: 'Billi'});
            cat.save(function (error, cat) {
                if (error) {
                    return done(error)
                }
                //   throw error;
                console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
                console.log('%j', cat);
                console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
                done();
            })
        });
    });
});

  • Error Handling In Nodejs Style

In nodejs there you need to define a callback to every single IO Async operation. You can pass callback of mocha to that IO operation. It will work like charm.


//7-error-handling-in-nodejs-style.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = require('../db/cat');
describe('Cat Modal', function () {
    describe('#create()', function () {
        it('should fail since cat is already created with name Deepak', function (done) {
            var cat = new Cat({name: 'Deepak'});
            cat.save(done)
        });
    });
});

  • Integrating With Mocha Hooks

Mocha provide us some predefined hooks like before(), after(), beforeEach(), afterEach(), that can be used on some predefined situation as per user requirement to clean the test cases.


//8-integrating-with-mocha-hooks.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var should = require('should')
var Cat = require('../db/cat');
describe('Connection', function () {
    var tobi = new Cat({name: 'tobi'})
        , loki = new Cat({name: 'loki'})
        , jane = new Cat({name: 'jane'});
    beforeEach(function (done) {
        Cat.remove({}, function (err) {
            console.log('collection dropped');
            Cat.create([tobi, loki, jane], done);
        });
    })
    describe('#find()', function () {
        it('respond with matching records', function (done) {
            Cat.find({}, function (err, res) {
                if (err) return done(err);
                res.should.have.length(3);
                done();
            })
        })
    })
});

To be continued

<Go 2 Top>

contact:me

 

FOUND THIS USEFUL? SHARE IT

Leave a comment -