Marie Cruz


API Testing using Jest and SuperTest

Last week, I’ve been playing around with how to integrate SuperTest, a library for testing HTTP servers. With over 2 million weekly downloads, it seems to be a standard choice for testing our backend API. Previously, I have blogged on how to use Cypress for API testing. While I could have use this to test our API, I’m a big advocate of using the right tool within the right context. As our team is all focused on backend work, it doesn’t make sense to introduce a front end testing tool like Cypress to test our APIs. In this blog post, I will show how you can integrate SuperTest with Jest to test your APIs.

Installing Dependencies

The first step that we need to do as always is to install the dependencies that we need. For this, you need to add the following to your project’s dev dependencies. If you are using TypeScript, you might need to install the type definitions as well.

npm i -D jest supertest

// if using TypeScript
npm i -D jest supertest @types/jest @types/supertest typescript

Babel Setup

In order to use the latest features of JavaScript, let’s quickly set up Babel. Babel allows us to convert new ES6 syntax into older versions of JavaScript that are backwards compatible. Since I’ll be using new syntax like the import statement on my test, this setup is needed.

For this specific Babel setup, I have chosen to use the @babel/preset-env plugin. This preset contains all the additional plugins that we would need to transpile all of our ES6 features.

Let’s again add it to our dev dependencies.

npm i -D @babel/preset-env

Then, create a .babelrc file and add the following setup. This setup will let us compile our code based on the current node version that we are using.

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

If this is still confusing and you want to know more about this plugin, I highly recommend giving their documentation a read through.

Writing our First Test

The next step is to structure our first test. For the first test, it’s a simple get request to this endpoint todos/1 and verifying that the status code is 200 as shown in the code snippet below.

import request from "supertest";

const baseUrl = 'https://jsonplaceholder.typicode.com/';

describe('Todos endpoint', () => {
	it('should return a 200 status code', async () => {
		const response = await request(baseUrl)
			.get('todos/1');

		expect(response.statusCode).toBe(200);
	});
}):

SuperTest has a function called request which is used to initialise the API call based on what’s being passed to it. Our base url here is the jsonplaceholder fake API which I’ve hard coded for simplicity. Afterwards, I’m simply calling the get function to simulate a get request to todos/1 endpoint. The async/await keyword is used to make our request synchronous and wait for the request to complete before doing the assertion that the status code should be 200.

Marking Todo Item as Completed

Now, let’s try to mark a todo item as completed and show how we can achieve that with SuperTest. For this test, we want to set completed to have the value of true when we do a put request to the same endpoint and then check that it’s successful by asserting the status code to be 200 and verifying that the response body matches our expectation.

it('should set the todo item to completed', async () => {
  const response = await request(baseUrl)
    .put('todos/1')
    .send({
        completed: true
    });

  expect(response.statusCode).toBe(200)
  expect(response.body).toMatchObject({completed: true, id: 1})
});

Rather than calling the get function, we are now using the put function to simulate a put request to todos/1 endpoint. Next, I’m calling the send function and passing in an object that will set completed to true.

Wrapping Up

That’s pretty much it! SuperTest is a very easy to use library for testing APIs whether it’s REST based or GraphQL. The examples above are pretty basic but should help you get started. Apart from doing a get or put request, you can also invoke other HTTP actions, set authorisation token, cookies or any custom headers. For more examples on how to use the library, check out SuperTest documentation.

All the code snippets above can be seen on my supertest-demo github repository so feel free to clone or download it.