Here are the links to the previous installments:

I probably don?t have to tell you for the umpteenth time about the importance of TDD and writing unit tests for your code. This is a non-negotiable discipline regardless the platform or programming language you?re using. With JavaScript being a dynamic language, this becomes even more important because you don?t have a compiler to fall back on that takes care of the most general sanity checks.

Some time ago, during my first explorations of JavaScript, I stumbled upon this simple BDD framework called jasmine. Using jasmine-node, this small specification framework can be made available for Node.js as well. For this blog post I?ll be showing some of the basic usages.

In order to install jasmine-node, you can either use npm

npm install jasmine-node

or use Git to get the latest version of the lib folder that contains the following three JavaScript files:

Now we can start using jasmine-node. Let?s look at an example of a suite.

var Customer = require( 'domain' ).Customer, Order = require( 'domain' ).Order, OrderItem = require( 'domain' ).OrderItem, should = require( 'should' ); describe( 'When making a regular customer preferred' , function () { var _order = new Order([ new OrderItem(12), new OrderItem(16) ]), _totalAmountWithoutDiscount = _order.getTotalAmount(); _customer = new Customer([ _order ]); _customer.makePreferred(); it( 'should mark the customer as preferred' , function () { _customer.isPreferred().should.be. true ; }); it( 'should apply a ten percent discount to all outstanding orders' , function () { _order.getTotalAmount().should.equal(_totalAmountWithoutDiscount * 0.9); }); });

Specifications are organized in suites. A suite is defined by providing a describe() function with a description. It?s also possible to nest suites, although I wouldn?t recommend that as it doesn?t work as one might expect. In this example we set up a regular customer which we then turn into a preferred customer. A specification is defined by providing an it() function with a description. For the actual verifications I opted for using should.js which provides BDD style assertions that are test framework agnostic instead of the matchers built into Jasmine.

// Built-in matchers expect(_customer.isPreferred()).toBeTruthy(); expect(_order.getTotalAmount()).toEqual(_totalAmountWithoutDiscount * 0.9)); // Should.js _customer.isPreferred().should.be. true ; _order.getTotalAmount().should.equal(_totalAmountWithoutDiscount * 0.9);

I really like the syntax provided by should.js, but that?s just my personal opinion of course.

Note that suites are just plain old JavaScript functions that are executed only once. This therefore means that our setup code is also executed only once. I particularly like this as it prevents context betrayal and forces the specifications to just observe the outcome.

However, it?s also possible to provide a function that runs before each specification.

var Customer = require( 'domain' ).Customer, Order = require( 'domain' ).Order, OrderItem = require( 'domain' ).OrderItem, should = require( 'should' ); describe( 'When making a regular customer preferred' , function () { var _order, _totalAmountWithoutDiscount, _customer; beforeEach( function () { _order = new Order([ new OrderItem(12), new OrderItem(16) ]), _totalAmountWithoutDiscount = _order.getTotalAmount(); _customer = new Customer([ _order ]); _customer.makePreferred(); }); it( 'should mark the customer as preferred' , function () { _customer.isPreferred().should.be. true ; }); it( 'should apply a ten percent discount to all outstanding orders' , function () { _order.getTotalAmount().should.equal(_totalAmountWithoutDiscount * 0.9); }); });

Now, we?ll need to provide some plumbing in order to execute these specifications using Node.js. We need to provide a small script that picks up all specifications for a particular folder and feed these to jasmine for executing them.