Chovy's Blog

Web Development with Node.js, Javascript, and HTML5

By

Testing a node.js express app with Mocha and Should.js

I’ve been doing more Test Driven Development the past few months with my node.js application code base.

With my latest project Wishd.me, I decided to get started early with writing tests. While skeptical at first, I have to admit it does save quite a bit of effort in debugging and peace of mind when it comes to the stability of the code.

There are a few options with Node.js, but I decided to use the Mocha framework and Should.js for testing my models and libraries.

For the User Interface I record Selenium tests using the Selenium IDE for Firefox. This has caught quite a lot of bugs as I run the Selenium test suite before every deploy as a means of acceptance testing.

Here’s a simple unit test I wrote to get things started. I created a file in ./test/model.item.js and imported the modules and libraries I need (mongoose, User model and Item model). I’m using Mocha and Should.js for the testing language.

In case there is a database error, we trap it — I had an issue where I was getting the following error when running my mocha tests:

…so trapping the error will fix the above promblem.

I was a little worried I might actually delete data from the wrong database if I accidently ran my tests on development or production databases instead of my test database, so I forced a check for the NODE_ENV variable to be test in each unit test before any tests are executed:

Since this is a test run, I want to just drop whatever is in the database after I’m done with tests so we don’t have strange errors arise from pre-existing data:

BE VERY CAREFUL AS YOU WILL LOOSE ALL DATA — You can read my previous article on backing up a mongodb first

You can put one ‘after()’ statement above all else that will run when all tests are finished.

Ok, now we are ready to write some mocha tests using the Should.js library. Let’s describe the first User model tests.

Basically, I am removing all users before each test, since we create a fakeUser in the first test (see beforeEach):

After all tests, I will remove the User and the Item that were created previously. Note that each callback takes a ‘done’ function that can be called at the end of your test.

Here is a nested describe() unit test that will test the #save() function of the User model.

Here we use the Should.js library to describe and test what attributes should be in the unit test (this is the heart of the unit test).

Now to tie things together and so all you have to do to run tests is type ‘make test’, we need to add the following Makefile to your root directory (be sure there is a ./test subdirectory):

…and finally, in package.json you can add the following line, so you can run ‘npm test’ to run your unit tests:

To install Mocha and Should.js you can use the following commands:

  • Michael Z.

    The part about Error: Trying to open unclosed connection — You should be using mongoose.createConnection instead of mongoose.connect. That’s why you’re getting the error.

    More info: http://stackoverflow.com/questions/15712226/mongoose-trying-to-open-unclosed-connection

  • stiivo

    Well, this is actually only testing of mongoose model – usefull, but not what I was looking for.

  • baris

    mentions express in the title but nowhere else, was hoping for something more express related.

  • Thomas

    You might want to check out monky to avoid passing fake data around once you have multiple test files: https://github.com/mbehrendt/monky