These are some of the tools I use to test my Node.js code:

  1. Mocha is a testing framework for describing and running tests
  2. Chai is an assertion library
  3. Sinon is a mocking and stubbing library

In this post I will give a brief introduction to each of these, with some basic examples and tips.

Mocha

Mocha.js is a test running framework. Install Mocha with npm install -g mocha. Run mocha to execute all the javascript test files in the test directory.

Some example Mocha tests are: var assert = require("assert")``describe('mocha', function(){ it('should fail when throwing an error', function(){ throw "FAIL" })``it('should fail when asserting false', function(){ assert(false) })``it('should pass when finishing without error', function(){ })``it('should pass when asserting true', function(){ assert(true) })``it('should be pending with no function') })

  • describe is used to organise your tests
  • it takes a test’s name and function (no function makes the test pending)

Running mocha for these tests will output: mocha 1) should fail when throwing an error 2) should fail when asserting false ✓ should pass when finishing without error ✓ should pass when asserting true - should be pending with no function``2 passing (5ms) 1 pending 2 failing``1) mocha should fail when throwing an error: Error: the string "FAIL" was thrown, throw an Error :) at <STACKTRACE>``2) mocha should fail when asserting false: AssertionError: false == true at <STACKTRACE>

Chai

Chai is an assertion library which can be used with Mocha to write readable tests. Chai can be installed with npm install chai and it is used like: var chai = require('chai') chai.should()``describe('chai', function(){ it('should fail when asserting false', function(){ false.should.equal(true) })``it('should pass when testing type', function(){ "string".should.be.a("string") })``it('should pass when testing include', function(){ [1,2,3].should.include(2) }) })

Calling chai.should() adds the should object to the Object prototype which lets you write tests that read like English with Chai’s many testing methods.

Note: I prefer the should style of testing, but Chai also supports the expect style.

Sinon

Sinon is a mocking and stubbing library that can be used to replace functions on an object with fake, inspectable functions. Sinon can be installed with npm install sinon and used like: var chai = require('chai') chai.should()``var sinon = require('sinon')``var Test = { do: function(thing){ return "no"} }``describe('sinon', function(){ it('should stub a method', function(){ Test.do("thing").should.equal("no")``sinon.stub(Test, "do", function(){return "yes"}) Test.do("thing").should.equal("yes")``Test.do.restore() Test.do("thing").should.equal("no") })``it('should validate if a function is called', function(){ sinon.stub(Test, "do", function(){return "yes"})``Test.do.calledOnce.should.be.false``Test.do("thing").should.equal("yes") Test.do.calledOnce.should.be.true``Test.do.restore() })``it('should validate a functions parameters', function(){ sinon.stub(Test, "do", function(thing){ thing.should.equal("thing") return "yes" })``Test.do("thing").should.equal("yes") Test.do.calledOnce.should.be.true``Test.do.restore() }) })

Sinon’s stub method takes an object and the name of the function to stub, and replaces that function with a ‘spy’. You can assert a spy has been called with calledOnce, change the output the spy returns, and test the arguments that are passed to it.

restore should be called on the spy at the end of a test to restore the old function back to the object, otherwise it will stay stubbed for the next test.

Promises

If you return a promise in a mocha test it will fail if that promise is rejected. For example, using the q promise library: var chai = require('chai') chai.should()``var q = require('q')``describe('promises', function(){ it('should pass if returning resolved promise', function(){ var d = q.defer() d.resolve("PASS") return d.promise })``it('should fail if returning failed promise', function(){ var d = q.defer() d.reject("FAIL") return d.promise }) })

This makes testing async code much easier.

Default settings

Mocha has a rich set of options to customise your running tests.

Instead of adding many arguments each time you run mocha you can create the file test/mocha.opts which contains your default options.

In mocha.opts can be specified a common test helper, common code that each test requires. Adding –require test/test_helper to test/mocha.opts will require test/test_helper.js file before each test. In this helper we could, for example, move the common chai requirements: var chai = require('chai') chai.should()

You can also specify different test compilers in mocha.opts. I typically write code in CoffeeScript (for reasons described here). Mocha supports this choice, and by adding –compilers coffee:coffee-script/register to test/mocha.opts it will execute all the tests written in CoffeeScript.

Further Reading

My previous post on Testing promises in Node.js with Mocha, Chai and Sinon.

Node.js in Action

Node.js the Right Way