How to Write Your First Test With Mocha

How to Write Your First Test With Mocha

The goal of this mini-project is to add a few tests for Blog.
The project is on GitHub at https://github.com/azat-co/blog-express.

We won’t get into headless browsers and UI testing, but we can send a few HTTP requests and parse their responses from the app’s REST end points.

The source code for this tutorial is in the ch3/blog-express folder of the practicalnode GitHub repository (https://github.com/azat-co/practicalnode).

First, let’s copy the Hello World project. It will serve as a foundation for Blog. Then, install Mocha in the Blog project folder, and add it to the package.json file at the same time with $ npm install mocha@1.16.2 --save-dev.

The --save-dev flag will categorize this module as a development dependency (devDependencies).

Modify this command by replacing package name and version number for expect.js v0.2.0 and superagent v0.15.7 (https://npmjs.org/package/superagent). The latter is a library to streamline the making of HTTP requests. Alternatives to superagent include the following:

  • request(https://npmjs.org/package/request): the third most-starred NPM module (as of this writing)
  • core http module: clunky and very low level
  • supertest: a superagent-based assertions library

Here’s the updated package.json:

{
  "name": "blog-express",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js",
    "test": "mocha test"
  },
  "dependencies": {
    "express": "4.1.2",
    "jade": "1.3.1",
    "stylus": "0.44.0"
  },
  "devDependencies": {
    "mocha": "1.16.2",
    "superagent": "0.15.7",
    "expect.js": "0.2.0"
  }
 }

Now, create a test folder with $ mkdir tests and open tests/index.js in your editor.

The test needs to start the server:

    var boot = require('../app').boot,
      shutdown = require('../app').shutdown,
      port = require('../app').port,
      superagent = require('superagent'),
      expect = require('expect.js');
    describe('server', function () {
      before(function () {
        boot();
      });
    describe('homepage', function(){
      it('should respond to GET',function(done){
        superagent
          .get('http://localhost:'+port)
          .end(function(res){
            expect(res.status).to.equal(200);
            done()
        })
      })
    });
    after(function () {
      shutdown();
    });
  });

In app.js, we expose two methods, boot and shutdown, when the file is imported, in our case, by the test. So, instead of:

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

we can refactor into:


var server = http.createServer(app);
var boot = function () {
server.listen(app.get('port'), function(){
console.info('Express server listening on port ' + app.get('port'));
});
}
var shutdown = function() {
server.close();
}
if (require.main === module) {
boot();
}
else {
console.info('Running app as a module')
exports.boot = boot;
exports.shutdown = shutdown;
exports.port = app.get('port');
}

To launch the test, simply run $ mocha tests . The server should boot and respond to the home page request (/ route) as shown in Figure 3–3.

Figure 3–3. Running $ mocha tests
Figure 3–3. Running $ mocha tests

Putting Configs Into a Makefile

The mocha accepts many options. It’s often a good idea to have these options gathered in one place, which could be a Makefile. For example, we can have test, test-w test all files in the test folder, and have modes for just the module-a.js and module-b.js files to test them separately, this way:

REPORTER = list
MOCHA_OPTS = --ui tdd --ignore-leaks

test:
        clear
        echo Starting test *********************************************************
        ./node_modules/mocha/bin/mocha \
        --reporter $(REPORTER) \
        $(MOCHA_OPTS) \
        tests/*.js
        echo Ending test
test-w:
./node_modules/mocha/bin/mocha \
--reporter $(REPORTER) \
--growl \
--watch \
$(MOCHA_OPTS) \
tests/*.js

Now we can deal with a task that is targeting a single test:

test-module-a:
mocha tests/module-a.js --ui tdd --reporter list --ignore-leaks

test-module-b:

clear
echo Starting test *********************************************************
./node_modules/mocha/bin/mocha \
--reporter $(REPORTER) \
$(MOCHA_OPTS) \
tests/module-b.js
echo Ending test

Finally, we wrap things up with the list of all tasks:

.PHONY: test test-w test-module-a test-module-b

To launch this Makefile, run $ make <mode>—for example, $ make test. For more information on a Makefile please refer to Understanding Make at http://www.cprogramming.com/tutorial/makefiles.html and Using Make and Writing Makefiles at http://www.cs.swarthmore.edu/newhall/unixhelp/howto_makefiles.html.

For our Blog app, we can keep the Makefile simple:

REPORTER = list
MOCHA_OPTS = --ui bdd –c

test:
clear
echo Starting test *********************************************************
./node_modules/mocha/bin/mocha \
--reporter $(REPORTER) \
$(MOCHA_OPTS) \
tests/*.js
echo Ending test

.PHONY: test

Note We point to the local Mocha in the Makefile, so the dependency needs to be added to package.json and installed in the node_modules folder.

Now we can run tests with the $ make test command, which allows for more configuration compared with the simple $ mocha tests(Figure 3–4 ).

Figure 3–4. Running make test
Figure 3–4. Running make test

Summary

In the previous Mocha article, we installed Mocha as a command-line tool and learned its options, we wrote simple tests with assert and the expect.js libraries.

In this tutorial, we created the first test for the Blog app by modifying app.js to work as a module.

Author: Azat

Techies, entrepreneur, 20+ years in tech/IT/software/web development expert: NodeJS, JavaScript, MongoDB, Ruby on Rails, PHP, SQL, HTML, CSS. 500 Startups (batch Fall 2011) alumnus. http://azat.co http://github.com/azat-co

3 thoughts on “How to Write Your First Test With Mocha”

  1. I haven’t see that many projects with mocha.conf. I think Makefile is a more popular standard.

    If you publish a module, think about other developers. “make something” is easier to use for them than something very specific to this framework (Mocha).

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.