Test-Driven Development in Node.js With Mocha

Courses on Node.js, React
and JavaScript
Become an expert with my comprehensive
Node.js, React.js and JavaScript courses.
Learn Full Stack Javascript →


Who needs Test-Driven Development?

Imagine that you need to implement a complex feature on top of an existing interface, e.g., a ‘like’ button on a comment. Without tests you’ll have to manually create a user, log in, create a post, create a different user, log in with a different user and like the post. Tiresome? What if you’ll need to do it 10 or 20 times to find and fix some nasty bug? What if your feature breaks existing functionality, but you notice it 6 months after the release because there was no test!

Mocha: simple, flexible, fun

Mocha: simple, flexible, fun

Don’t waste time writing tests for throwaway scripts, but please adapt the habit of Test-Driven Development for the main code base. With a little time spent in the beginning, you and your team will save time later and have confidence when rolling out new releases. Test Driven Development is a really really really good thing.

Quick Start Guide

Follow this quick guide to set up your Test-Driven Development process in Node.js with Mocha.

Install Mocha globally by executing this command:

$ sudo npm install -g mocha

We’ll also use two libraries, Superagent and expect.js by LeanBoost. To install them fire up npm commands in your project folder like this:

$ npm install superagent
$ npm install expect.js   

Open a new file with .js extension and type:

var request = require('superagent');
var expect = require('expect.js');

So far we’ve included two libraries. The structure of the test suite going to look like this:

describe('Suite one', function(){
  it(function(done){
  ...
  });
  it(function(done){
  ...
  });
});
describe('Suite two', function(){
  it(function(done){
  ...
  });
});

Inside of this closure we can write request to our server which should be running at localhost:8080:

...
it (function(done){
  request.post('localhost:8080').end(function(res){
    //TODO check that response is okay
  });
});
...

Expect will give us handy functions to check any condition we can think of:

...
expect(res).to.exist;
expect(res.status).to.equal(200);
expect(res.body).to.contain('world');
...

Lastly, we need to add done() call to notify Mocha that asynchronous test has finished its work. And the full code of our first test looks like this:

var request = require('superagent');
var expect = require('expect.js');
  
describe('Suite one', function(){
 it (function(done){
   request.post('localhost:8080').end(function(res){
    expect(res).to.exist;
    expect(res.status).to.equal(200);
    expect(res.body).to.contain('world');
    done();
   });
  });
});

If we want to get fancy, we can add before and beforeEach hooks which will, according to their names, execute once before the test (or suite) or each time before the test (or suite):

before(function(){
  //TODO seed the database
});
describe('suite one ',function(){
  beforeEach(function(){
    //todo log in test user
  });
  it('test one', function(done){
  ...
  });
});

Note that before and beforeEach can be placed inside or outside of describe construction.

To run our test simply execute:

Sidenote: If you like this post and interested in a corporate on-site JavaScript, Node.js and React.js training to boost productivity of your team, then contact NodeProgram.com.

$ mocha test.js

To use different report type:

$ mocha test.js -R list
$ mocha test.js -R spec
Courses on Node.js,
React and JavaScript
Become an expert with my comprehensive
Node.js, React.js and JavaScript courses.
Learn Full Stack Javascript →

[Sidenote]

Reading blog posts is good, but watching video courses is even better because they are more engaging.

A lot of developers complained that there is a lack of affordable quality video material on Node. It's distracting to watch to YouTube videos and insane to pay $500 for a Node video course!

Go check out Node University which has FREE video courses on Node: node.university.

[End of sidenote]

--
Azat Mardan
Azat Mardan avatar
https://www.linkedin.com/in/azatm
To contact Azat, the main author of this blog, submit the contact form.

Also, make sure to get 3 amazing resources to FREE when you sign up for the newsletter.
Simple.
Easy.
No commitment.

17 thoughts on “Test-Driven Development in Node.js With Mocha

  1. Dave

    Why aren’t you using the mocha framework’s suite(), and so on functions? You type ‘Suite’ in the name of the test, why is that?

  2. marcin

    Hi,

    I am trying to run my simple node server test;
    when i run my test i am getting ‘pending’ all the time in blue;
    what am i missing?

    best

    marcin

  3. Peter

    I am interested in the before hook in relation to the beforeEach hook. I have been testing an Angular application and there are issues when I attempt to instantiate modules in the before hook. Is this due to when the before hook is run, and perhaps I don’t have access to the inject provider of Angular at this time. I don’t expect Angular answers here but was hoping you could shed some light on the timing of before vs beforeEach

  4. Juan F

    In the it sentence, I thinks there is a mistake, it seems that you should include some text first, and then the callback following the text. In this way the test will show up as pending…

    Thanks for sharing this information, it was really helpful for me.

  5. Nomikos

    Thank you! In one paragraph you have managed to explain what Mocha actually *IS FOR*, something I could not grasph from their homepage. This happens way too often on newer front-end tools.. you need to know what it is and how it works before you can even understand the manual/documentation..

  6. Pingback: MEAN 2

  7. Pingback: mocha를 이용한 node.js | Beagle Bone Black with node.js

  8. Pingback: Final Research Links | Recipe Finder

  9. Jay Scott ANDERSON

    The example is apparently missing closing brackets, “request.post(‘localhost:8080’).end(” not closed.

  10. Pingback: Faysal Ahmed

Leave a Reply

Your email address will not be published. Required fields are marked *