Getting Started With Writing API Tests in Node JS
Before we get started with the technical details it’s important to understand why we even need API Tests.
APIs are the core part of any application. The behaviour of a particular API should not change for the same input. Writing tests help in making sure that we abide by this.
Even for future updates, we can simply run our tests to verify that our update hasn’t changed the behaviour of the API. It also helps in finding bugs early on in the development.
In this article, we will be using Mocha, Chai and SuperTest.
Mocha is one of the most popular Javascript Test Framework. It provides us with the environment to run our tests. Success, errors and exceptions are shown along with the test cases which makes it easier to understand.
Chai is the assertion library that we will be using. It supports both Behaviour-Driven Development(BDD) and Test-Driven Development(TDD) programming styles for testing. For this article, we will consider BDD.
SuperTest is an npm module which can be used to test HTTP endpoints. This works with any test framework.
Now, that we have briefly discussed the packages we will be using, let’s roll on to writing tests already.
For this article, let’s assume we have a simple API to create a wallet for a user.
POST /:user_id/wallet
201 CREATED
Location: /:user_id/wallet
Let’s create our test file test/test.js
and import the required packages.
const express = require('express');
const chai = require(‘chai’);
const request = require(‘supertest’);
Mocha provides us with two function calls describe()
and it()
describe()
helps in grouping our tests. For eg, we can keep all the test cases for an API under one describe
block.
It takes two arguments: the name of the test group and a callback function.
describe('POST Create User Wallet', () => {});
it()
is used for writing individual test cases. It takes two arguments: the name of the test describing what the test is supposed to do and a callback function where we write our actual test.
it('should create wallet for the user', () => {});
Let’s use these in our test file.
const express = require('express');
const chai = require(‘chai’);
const request = require(‘supertest’);const app = express();describe('POST Create User Wallet', () => {
it('should create wallet for the user', () => {
// code for testing the api});
});
expect
and should
are two BDD interfaces provided by Chai
which can be chained with getters to
be
etc to verify our results. You can check out all the available language chains here.
supertest
will be used to test our API endpoint. We will pass app
as an argument to this.
describe('POST Create User Wallet', () => {
it('should create wallet for the user', () => {
request(app)
.post('123456/wallet')
.send({})
.expect(201)
.then((res) => {
expect(res.headers.location).to.be.eql('123456/wallet');
// more validations can be added here as required
});
});
});
And that is it! We have successfully written the logic for our test.
Now, let’s see how to run it.
Mocha automatically looks for tests inside the test
directory. We can change test
the script in package.json
to run tests using mocha.
// package.json
{
"scripts": {
"test": "mocha"
}
}
Now our test can be run using npm run test
. Mocha will display the info related to the test along with it. It also displays the number of passed and failed tests at the end.
And we are all done!
Don’t worry if you are just starting with writing tests. As with anything, the more you practise, the better you get. It’s a skill worth learning so write lots and lots of tests.
Note:
It’s better to keep the database for testing separately. While testing we create and delete a lot of test data and it’s not a good idea to do all of this in the main database. Also, after our test has run we should truncate the tables so that we don’t run into issues like UniqueConstraint Error.