Getting Started

Note that, to follow along, clone the Master branch. It contains the starter movies API with GET /movies and POST /movies endpoints to retrieve all movies and post new movies respectively.

The completed code can be found in the Completed branch of the repository.

Introduction to Testing

Quickly, let’s brush up on the types of testing. There are basically 3 types of testing namely:

(a) Unit Testing: As the name implies, this is the testing of the smallest testable unit of your code. For example, testing of functions or modules in your code. You can test for the return type or value of your function, its parameter or the logic your function performs.

(b) Integration Testing: Here, you tests the interaction between 2 or more functions. That is, the testing of how 2 or more units work together.

(c.) End-to-End Testing: This is the testing of the combination of multiple integrations. It may include testing of an API, which connects to database and saves/retrieves data. This test comprises of many integrations.

Setting Up Testing Environment

We would be using Jest as our preferred testing framework. To install Jest, cd into the movies-api directory and run

npm install jest --save-dev

For Jest to see our test files, it must satisfy any of these 3 conditions:

Test files must be in a folder named __test__ File names should have .test.js suffix. E.g movies.test.js or user.test.js File names should have .spec.js suffix. E.g movies.spec.js or user.spec.js

Writing Your Test

Inside the src folder, create another folder named __test__ Inside it, create new file called movies.spec.js

You should therefore have a structure like this:

|- src

|- __test__

|- movies.spec.js

Jest uses describe , expect , and it in its framework.

describe lets you write multiple test cases inside it. It takes user-readable text and a callback function.

expect lets you write what you expect the test case to do.

it tells user what exactly should be carried out, otherwise called assertions.

Let’s code!

First, we will test if our testing framework works by writing a failed test, then write a test that would pass.

In your movies.spec.js , write the code:

// movies.spec.js describe("Testing the movies API", () => { it("tests our testing framework if it works", () => { expect(2).toBe(4); }); });

In your package.json, change the value of ‘test’ to: “jest”, like so:

Then run npm run test

The above was written to test our Jest framework. We expected 2 to be equal to 4, which would fail.

Our expected failed test

Let’s correct it and see what happens:

// movies.spec.js describe("Testing the movies API", () => { it("tests our testing framework if it works", () => { expect(2).toBe(2); }); });

Our passed test

Testing the Base API Endpoints

First we’ll install supertest for making API calls. Then we make our calls asynchronously since we are making API calls that might take a few seconds to return value to us. Let’s continue coding:

Run npm install supertest --save-dev to install supertest so can make calls.

Run npm run test and you will have a passing test case. In the above, we expect the response to be OK (status 200) and also return our body status of ‘true’

It is important to note that you use .toBe to check exact equality, like expect(2 + 2).toBe(4)

But you use .toEqual to check the value of an object. It does a deep check on object. E.g

let info = {one: 1}

info['two'] = 2; expect(info).toEqual({one: 1, two: 2}

Testing the GET /movies Endpoint

Now, lets tests for the GET /movies endpoint and ascertain if it will return an array. Update your movies.spec.js like so:

Run npm run test again and see the 2 assertions passing:

Our 2 test cases are passing

Testing the POST /movies Endpoint

Under this section, I’ll introduce some important concepts:

When running API tests on database, do not use production database as we’ve been using in this tutorial. A test contains 3 parts: prepare, action, assertion beforeEach afterEach

beforeEach is run before each test, which could include clearing the database or entering data in the database. For instance, if you want to test GET method, you might need to preload the table with existing data.

afterEach is run after a test case is performed. It might include removing the data added during the test.

We will be using afterEach in our case. We will add a movie object, run the test and remove it after the test. Lets code:

As usual, run the npm run test to run our test.

Yippee!! All our tests are passing.

Conclusion

We have successfully implemented Tests in our Node JS API using Jest and Supertest. This concept applies for almost all testing frameworks.

Writing tests improves the quality of your code. I implore you to add it to your code and watch as you write better codes.

Did this tutorial help you? Tweet at me or drop an awesome comment.

I’m here on Github and Twitter