Instantly share code, notes, and snippets.

Embed
What would you like to do?
Mocha Tutorial

Testing Node.JS applications using Mocha

Mocha is a unittest framework for Node. In this document, we explain how you can test your javascript code and also your HTTP servers.

Installing Mocha

Use npm to install Mocha:

npm install mocha

npm installs Mocha in node_modules/mocha/bin/mocha. You can run Mocha test cases using the following command:

node_modules/mocha/bin/mocha test

By default, Mocha will run test.js in the current folder. Now, let's explain how you can write a test case.

Testing a Library

Let say, we have a calc.js file that implements addition and multiplication:

exports.add = function(i, j) {
	return i + j;
};

exports.mul = function(i, j) {
	return i * j;
};

We should write unit tests to make sure that there is no bugs in add and mul. We implement our test cases in test.js:

var assert = require('assert');

var calc = require('./calc.js');

// Tests are hierarchical. Here we define a test suite for our calculator.
describe('Calculator Tests', function() {
	// And then we describe our testcases.
	it('returns 1+1=2', function(done) {
		assert.equal(calc.add(1, 1), 2);
		// Invoke done when the test is complete.
		done();
	});

	it('returns 2*2=4', function(done) {
		assert.equal(calc.mul(2, 2), 4);
		// Invoke done when the test is complete.
		done();
	});
});

assert is a standard module that provides easy-to-use assertion functions. calc is our calculator module.

describe creates a suite of test cases, and it implements a test case. The first argument to it is an explanation of the test case, and the second parameter is the test case function to which Mocha passes a done object. done should be called whenever the test case is finished. Inside the test case function, you should implement your test. For example, we have checked that add(1, 1) returns 2, and mul(2, 2) return 4.

Now, if you run Mocha you should see the following output:

# node_modules/mocha/bin/mocha test


  Calculator Tests
    ✓ returns 1+1=2
    ✓ returns 2*2=4


  2 passing (6ms)

Usually we test much larger applications, and we need a better categorization for our test cases. For that reason, you can embed a describe in another describe. For instance, if we want to have separate test cases for addition and multiplication, we implement test.js as follows:

var assert = require('assert');

var calc = require('./calc.js');

describe('Calculator Tests', function() {
	describe('Addition Tests', function() {
		it('returns 1 + 1 = 2', function(done) {
			assert.equal(calc.add(1, 1), 2);
			done();
		});

		it('returns 1 + -1 = 0', function(done) {
			assert.equal(calc.add(1, -1), 0);
			done();
		});
	});

	describe('Multiplication Tests', function() {
		it('returns 2 * 2 = 4', function(done) {
			assert.equal(calc.mul(2, 2), 4);
			done();
		});

		it('returns 0 * 4 = 4', function(done) {
			assert.equal(calc.mul(2, 2), 4);
			done();
		});
	});
});

For this test.js, you should get the following output:

# node_modules/mocha/bin/mocha test


  Calculator Tests
    Addition Tests
      ✓ returns 1 + 1 = 2
      ✓ returns 1 + -1 = 0
    Multiplication Tests
      ✓ returns 2 * 2 = 4
      ✓ returns 0 * 4 = 4


  4 passing (6ms)

Testing a Server

There is nothing special about testing a server except that we need to run the server to be able to test that. Well, you shouldn't do that manually. After all, unit tests are all about automation.

Let's first write a simple HTTP server that echos 'Hello, Mocha!' when we send a get request to /:

var http = require('http');

// This is just an example HTTP server. Use your own application here.
var server = http.createServer(function(req, res) {
	res.writeHead(200);
	res.end('Hello, Mocha!');
});

// listen strats the server on the given port.
exports.listen = function(port) {
	console.log('Listening on: ' + port);
	server.listen(port);
};

// close destroys the server.
exports.close = function() {
	server.close();
};

You can use any framework that you'd like including express.js. The only important point is that you should somehow export the functions to start and stop the server. Here, we have exported listen(port) and close().

Now, let's implement test.js:

var http = require('http');
var assert = require('assert');

var server = require('./server.js');

describe('HTTP Server Test', function() {
	// The function passed to before() is called before running the test cases.
	before(function() {
		server.listen(8989);
	});

	// The function passed to after() is called after running the test cases.
	after(function() {
		server.close();
	});

	describe('/', function() {
		it('should be Hello, Mocha!', function(done) {
			http.get('http://127.0.0.1:8989', function(response) {
				// Assert the status code.
				assert.equal(response.statusCode, 200);

                                var body = '';
				response.on('data', function(d) {
					body += d;
				});
				response.on('end', function() {
					// Let's wait until we read the response, and then assert the body
					// is 'Hello, Mocha!'.
					assert.equal(body, 'Hello, Mocha!');
					done();
				});
			});
		});
	});
});

before and after are the functions you can use to run a code before starting and after finishing all testcases in your suite. In our example, we start run the server on port 8989 in before, and close it in after.

Now, we know that the server will be running. So, we just send a get request using http.get(), read the response, and make sure that the server has echoed 'Hello, Mocha!'

Have fun hacking with Mocha!

@javaeeeee

This comment has been minimized.

javaeeeee commented Apr 9, 2016

Great Tutorial! Thanks!

@sunilkumarc

This comment has been minimized.

sunilkumarc commented Feb 20, 2017

Awesome tutorial. Thanks 👍

@leolanese

This comment has been minimized.

leolanese commented May 16, 2017

good stuff!

@dheerajsravi

This comment has been minimized.

dheerajsravi commented Jul 5, 2017

Thanks!!

@shai93

This comment has been minimized.

shai93 commented Jan 7, 2018

Thank you so much !!!!! :)

@KimBye

This comment has been minimized.

KimBye commented Jan 31, 2018

You rock, thanks.

@stealthanthrax

This comment has been minimized.

stealthanthrax commented Feb 3, 2018

Great tutorial 👍

@mateenrehan

This comment has been minimized.

mateenrehan commented Feb 22, 2018

Great tutorial!!!! Very simple and to the point and easy to understand.

@saeedkhan-github

This comment has been minimized.

saeedkhan-github commented Feb 27, 2018

where can i get further documentation and tutorials ?

@YinChaoOnline

This comment has been minimized.

YinChaoOnline commented Apr 14, 2018

a great intro tutorial for mocha!

@johngorithm

This comment has been minimized.

johngorithm commented Jun 18, 2018

Nice.... but can I use the request node package to make the request instead of the built in http module

@JamieBort

This comment has been minimized.

JamieBort commented Jun 22, 2018

Thank you!

@thydev

This comment has been minimized.

thydev commented Jul 2, 2018

Nice... it's so easy to understand!

@dianavile

This comment has been minimized.

dianavile commented Jul 18, 2018

Loved it, thanks for sharing. Was able to made first testing in Mocha:)

@nickprudnik

This comment has been minimized.

nickprudnik commented Jul 19, 2018

Very nice! Thanks for this tutorial

@aderonkeakinyemi

This comment has been minimized.

aderonkeakinyemi commented Aug 20, 2018

thank you for your help!

@zacscoding

This comment has been minimized.

zacscoding commented Nov 23, 2018

thx for help :)
there is a typo
it('returns 0 * 4 = 4', function(done) {
assert.equal(calc.mul(2, 2), 4);
done();
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment