I’ve wanted to hack on a node.js project for a while, and a new app idea has given me the perfect excuse. My first question was: how do I test this? It’s a fairly new field out there, and there isn’t much help from node.js itself: it’s much more like Rack than a proper framework. So I spent some time coming up with one way to do it.
This is what I’ve got so far (the actual app I’m working will remain closed-source for the mo):
You probably want to refer to the code whilst reading the rest of this article.
To run the tests, run rake. To start the app, run node app.js (you will need to have node.js installed obviously).
If you install the watchr gem, and run watchr autotest.watchr, you’ll get robust autotest like functionality. I’m liking watchr much better than ZenTest right now.
How it works
The basic premise is to decouple the request/response handler from the server (see app.js, lib/http.js and lib/router.js). The interesting bit is in test/ integration/ user_sees_homepage.js - this then calls the dispatch method directly, passing in dummy Request and Response objects.
Note how I’ve defined the Response object. This allows me currently to write an integration test that looks like this:
The assert.contains() method is not part of node.js: it’s implemented in test/helper.js.
The reason you need the asserts to be fired in the end() function is that node.js is inherently asynchronous and will finish executing this file whilst waiting for the haml file to load in lib/router.js. Try it yourself: if you put an assert at the bottom of the file it will fire immediately.
You could potentially use the Sinatra-like framework Express to define lib/router.js - I’ve handrolled it for the moment. I’m of the opinion that you spot betterrefactorings by handrolling to start with: it could be that express.js isn’t right for my app, and I can’t easily tell yet.
If you use it for something useful, let me know! I’d be very happy to receive patches and suggestions.
Ealdorlight is now on Kickstarter! Use your connections to win the throne with intrigue or force. RPG with realistic damage and procedural storytelling for PC, Mac and Linux.