It's always difficult to start something new, isn't it? It took me some time to feel comfortable creating NodeJS applications, because I had a hard time figuring out how to start. After reading many about that on many places in the Internet I realized that more important than doing something right is to do it at all. With software development everything basically comes down to experience. There are some good practices that you should follow to avoid some of the most popular problems with given tool or language, but often you have to face them to see what works best for you. I am a TDD enthusiast and this is what I'm looking for whenever I start working with a language, library or a framework. This quick tutorial presents how to create a TDD environment with a minimal configuration.

The idea

We'll be building a very simple web application that will convert temperature between the two most popular scales: Celsius and Fahrenheit. We'll create handlers for two requests:

/convert/celsius?c=<celsius_value>

with the response being a Fahrenheit value calculated from <celsius_value> , and:

/convert/fahrenheit?f=<fahrenheit_value>

with the reverse conversion.

Set up NodeJS project

To start things up, we need a NodeJS project, so we need NodeJS and npm (Node's package manager). With these installed we can create an empty directory with one simple, yet very important file - package.json :

{ "name": "simple-nodejs-example", "version": "1.0.0" }

This is the minimal initial configuration for the application, as it defines just it's name and version. This is enough, as long as we don'w want to publish our app anywhere. If you think about going public with your work, consider adding more information about the app to make it easier for the community to understand it.

Set up TDD environment with Jasmine

The idea of TDD is simple:

You write a test for some functionality (test must fail) You write a piece of code (test has to pass) You refactor your code (test still passes)

There are many advantages of TDD which I might explain some other time, but for now let's stick to actually doing it. You'll thank me later. In this example we'll utilize probably the most popular JavaScript testing library - Jasmine.

Setting up Jasmine evironment in our project is more than simple. First we'll install the dependency and initialize it:

npm install --save jasmine node_modules/jasmine/bin/jasmine.js init

To run the tests we'll run:

node_modules/jasmine/bin/jasmine.js

That last command creates a spec directory in our project with spec/support/jasmine.json configuration file:

{ "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" ] }

The content of this file defines the location of tests and helpers (scripts that are not a production code, but will help in running tests correctly). Now we can create our first test file, spec/Converter.spec.js :

var Converter = require('../backend/Converter'); describe('Converter', function(){ it('should convert positive Celsius to Fahreheit', function(){ // given var converter = new Converter(); //when var result = converter.toFahrenheit(40); //then expect(result).toEqual(104); }); });

Our first test assumes that:

We have a class in <root>/backend/Converter.js file This class has a method toFahrenheit toFahrenheit(40) == 104

When we run the test we'll get error, because the file does not exist:

Error: Cannot find module '../backend/Converter'

Creating an empty file will not move us past step no 1, because the file has to be a npm module and return the class as module.exports :

TypeError: object is not a function

Let's create a class then:

function Converter() { } module.exports = Converter;

After running the tests we notice that first step is behind us

TypeError: Object #<Converter> has no method 'toFahrenheit'

and it's time to create the method:

this.toFahrenheit = function() { return 0; }

We're very close, because we just have incorrect value returned from the method:

Expected 0 to equal 104.

We can repeat this iteration until we have enough tests to cover all the important cases, but for now we can skip that.

Create simple server file

Now we have the application's logic ready and testef we can create the entry point into the application. We won't be using any frameworks that speed up node web application development, because it's not the purpose of this example. We'll cover tools like Express some other time. Now we just want to have out app up and running and conerting between two scales. The final version of app.js server file should look like this:

var http = require('http'); var url = require('url'); var Converter = require('./backend/Converter'); var converter = new Converter(); var server = http.createServer(function(req, res){ var urlObject = url.parse(req.url, true); var baseUrl = urlObject.pathname; var parameters = urlObject.query; if (baseUrl === '/celsius') { var celsius = parseInt(parameters.c, 10); var fahrenheit = converter.toFahrenheit(celsius); res.end(fahrenheit + '

'); } else if(baseUrl === '/fahrenheit') { var fahrenheit = parseInt(parameters.f, 10); var celsius = converter.toCelsius(fahrenheit); res.end(celsius + '

'); } else { res.end("Unsupported operation

"); } }); server.listen(2015);

Now we can run it and see that the values we're getting are correct:

$ curl localhost:2015/fahrenheit?f=104 40 $ curl localhost:2015/celsius?c=40 104

Summary

As you can see, creating a simple, yet well tested, node application is very easy thing to do. I encourage you to start every project with preparing the testing environment, because you will need this sooner than later.

View this example on Github