Source Allies Logo

Sharing Our Passion for Technology

& Continuous Learning

<   Back to Blog

Node Reference - Unit Testing

Teammates sitting together and looking at code

Prerequisites

This article builds on the prior article: Introduction.

Unit Testing

We plan on using Test Driven Development so we need to set up some sort of unit testing framework. For this task we're turning to Jasmine. Mocha/Chai/Sinon and Jest are also popular options. They are all similar but the thing that we like about Jasmine is that it includes a test runner, assertion library and a mocking framework all in one dependency.

Let's start by installing it by running:

npm install --save-dev jasmine

Because Jasmine is a behavior-driven development (BDD) framework for testing JavaScript, it results in a very readable specification as seen below. It is a good idea to exercise a new testing framework to get comfortable with how it works. Let's create a starter Jasmine specification by creating a hello.spec.js file with the following content:

describe('test case', function() {
    it('should say cheep', function() {
        expect(1).toEqual(2);
    });
});

By default, Jasmine looks for a config file at spec/support/jasmine.json relative to the root directory. Create that file with these contents:

{
    "spec_files": [
        "*.spec.js",
        "!(node_modules)/**/*.spec.js"
    ]
}

Finally, add a "scripts" entry to package.json by adding this snippet:

"scripts": {
  ...
  "test": "jasmine"
},

Running npm test will execute all test cases in the project (as long as the test files end in ".spec.js"). The above test will fail (because 1 != 2). Change it and rerun it to make sure it passes.

A few notes about unit testing in general and Jasmine specifically:

  1. It is very important to consider the asynchronicity of Javascript when choosing a testing library. The ideal case is that a test case can return a Promise. This allows a test case to be declared "async" and to simply await the execution of the system under test before asserting the results.
  2. We like to put the test case files in the same directory as the system under test. This way, it is easy to locate the test files, they are listed alphabetically immediately after the file they are testing. It also allows the require call to use a short, relative path.
  3. You may have noticed that I declared the describe and it callbacks as classic functions and not their arrow-function counterpart. Jasmine automatically creates an empty object and binds it to the callback functions. This allows us to reference this to store state between the beforeEach calls and the individual test cases.

Wrap-up

In this article, we learned how to setup some basic unit tests and why we chose one testing library over popular libraries. View the changes made during this post.

Now that we have a small service created and the ability to test-drive features we add to the service, we will use this to create the first endpoint in the next article.

Table of Contents

If you have questions or feedback on this series, contact the authors at nodereference@sourceallies.com.