So, you’ve built your Node.js backend with Express and now you need a clean and reliable approach to test it?

In this article, I’ll show you how you can use the supertest module to make testing your Express.js backend feel like a breeze!

First of all, here’s the sample app that has a single GET endpoint.

// server.js
import express from 'express';

const app = express();

app.get('/config', function(req, res) {
  res.json({ version: '0.0.1' });
});

export const server = app;

In our test, we want to make sure that GET /config returns status code 200, has a content type json, and that this JSON is exactly what it should be.

Before writing a test you can type npm install --save supertest to install and save the supertest module to node_modules. Also, I expect that you already have configured the testing environment with jest.

If you like the --save-dev option instead of --save or yarn instead of npm you can use it too. It doesn’t particularly matter here.

Once we have that in place, we can proceed to write tests.

So, to be able to test our Node.js backend with supertest, we need to import it into our test file and then create a function that we’ll use to do test requests to our server.

const requestWithSupertest = supertest(server);

Then, we can get a response from our system under test.

const res = await requestWithSupertest.get('/config');

Make sure to add await, as we need the request promise fulfilled before moving forward.

Now, after the request is done and the response is stored in the res variable, let’s add out assertions.

  expect(res.status).toEqual(200);
  expect(res.type).toEqual(expect.stringContaining('json'));
  expect(res.body).toEqual({ version: '0.0.1' });

As planned, we test 3 key points. Response status code, response type, and response body.

If you add everything up, you’ll get something like this.

// test.js
import '@babel/polyfill';            // support for async/await
import supertest from 'supertest';
import { server } from '../server.js';

const requestWithSupertest = supertest(server);

test('GET /config should be implemented according to the spec', async () => {
  const res = await requestWithSupertest.get('/config');
  expect(res.status).toEqual(200);
  expect(res.type).toEqual(expect.stringContaining('json'));
  expect(res.body).toEqual({ version: '0.0.1' });
})

A good idea might be to split these test cases into separate tests and maybe combine them under a single describe block. For demonstration purposes, there’s no need for that, though.


Testing your Node.js/Express.js backend with supertest is very convenient. You don’t have to reinvent the wheel. Just create a wrapper around an instance of your express.js server and send requests to it.