Skip to content

Instantly share code, notes, and snippets.

@soheilhy
Last active March 18, 2022 05:23
Show Gist options
  • Save soheilhy/867f76feea7cab4f8a84 to your computer and use it in GitHub Desktop.
Save soheilhy/867f76feea7cab4f8a84 to your computer and use it in GitHub Desktop.
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
Copy link

Great Tutorial! Thanks!

@sunilkumarc
Copy link

Awesome tutorial. Thanks 👍

@leolanese
Copy link

good stuff!

@dheerajsravi
Copy link

Thanks!!

@shai93
Copy link

shai93 commented Jan 7, 2018

Thank you so much !!!!! :)

@KimBye
Copy link

KimBye commented Jan 31, 2018

You rock, thanks.

@sansyrox
Copy link

sansyrox commented Feb 3, 2018

Great tutorial 👍

@mateenrehan
Copy link

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

@saeedkhan-github
Copy link

where can i get further documentation and tutorials ?

@YinChaoOnline
Copy link

a great intro tutorial for mocha!

@johngorithm
Copy link

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

@JamieBort
Copy link

Thank you!

@thydev
Copy link

thydev commented Jul 2, 2018

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

@dianavile
Copy link

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

@nickprudnik
Copy link

Very nice! Thanks for this tutorial

@aderonkeakinyemi
Copy link

thank you for your help!

@zacscoding
Copy link

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();
});

@poornimahabib
Copy link

nice tutorial for beginners..Thank you

@Kaushal28
Copy link

Better tutorial that it's docs

@szb512
Copy link

szb512 commented Feb 26, 2019

Awesome.

@dandgerson
Copy link

Thanks a lot! Greate Article. For more obviousness you can make bold that string wich contain that for test running we need started server )))

@AravindReddyGuda
Copy link

can you please help me by testing a function which does not return anything but console.log('.......')

@soheon
Copy link

soheon commented Jun 21, 2019

great!
I want to meet u.
Can I call u elder brother?

@sametpalitci
Copy link

Thank you

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