DEV Community

Cover image for Testing REST APIs using Jest and Supertest ✅
Souvik Kar Mahapatra
Souvik Kar Mahapatra

Posted on

Testing REST APIs using Jest and Supertest ✅

originally published: souvikinator.xyz

Here’s how to set up unit tests for API endpoints.

We’ll be using the following NPM packages:

  • Express for the server (any other framework can be used)
  • Jest
  • Supertest

VS Code extension using:

  • Jest
  • Jest Runner

Installing dependencies

npm install express
Enter fullscreen mode Exit fullscreen mode
npm install -D jest supertest
Enter fullscreen mode Exit fullscreen mode

Here is what the directory structure looks like:

directory structure

and lets not forget package.json

{
  "name": "api-unit-testing",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest api.test.js",
    "start":"node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.1"
  },
  "devDependencies": {
    "jest": "^28.1.2",
    "supertest": "^6.2.3"
  }
}
Enter fullscreen mode Exit fullscreen mode

Creating a simple express server

An express server that accepts POST requests with a body and title on the /post endpoint. If either one is missing, status 400 Bad Request is returned.

// app.js
const express = require("express");
const app = express();

app.use(express.json());

app.post("/post", (req, res) => {
  const { title, body } = req.body;

  if (!title || !body)
    return res.sendStatus(400).json({ error: "title and body is required" });

  return res.sendStatus(200);
});

module.exports = app;
Enter fullscreen mode Exit fullscreen mode
const app = require("./app");
const port = 3000;

app.listen(port, () => {
  console.log(`http://localhost:${port} 🚀`);
});
Enter fullscreen mode Exit fullscreen mode

The express app is exported for use with supertest. The same can be done with other HTTP server frameworks.

Creating test file

// api.test.js
const supertest = require("supertest");
const app = require("./app"); // express app

describe("Creating post", () => {
    // test cases goes here
});
Enter fullscreen mode Exit fullscreen mode

Supertest takes care of running the server and making requests for us, while we focus on testing.

The express app is passed to the supertest agent and it binds express to a random available port. Then we can make an HTTP request to the desired API endpoint and compare its response status with our expectation:

 const response = await supertest.agent(app).post("/post").send({
        title: "Awesome post",
    body: "Awesome post body",
 });
Enter fullscreen mode Exit fullscreen mode

We’ll create test for 3 cases:

  1. When both title and body are provided
  test("creating new post when both title and body are provided", async () => {
    const response = await supertest.agent(app).post("/post").send({
      title: "Awesome post",
      body: "Awesome post body",
    });

        // comparing response status code with expected status code
    expect(response.statusCode).toBe(200);
  });
Enter fullscreen mode Exit fullscreen mode
  1. When either of them is missing
  test("creating new post when either of the data is not provided", async () => {
    const response = await supertest.agent(app).post("/post").send({
      title: "Awesome post",
    });

    expect(response.statusCode).toBe(400);
  });
Enter fullscreen mode Exit fullscreen mode
  1. When both of them is missing
  test("creating new post when no data is not provided", async () => {
    const response = await supertest.agent(app).post("/post").send();

    expect(response.statusCode).toBe(400);
  });
Enter fullscreen mode Exit fullscreen mode

and the final code should look like:

const supertest = require("supertest");
const app = require("./app"); // express app

describe("Creating post", () => {

  test("creating new post when both title and body are provided", async () => {
    const response = await supertest.agent(app).post("/post").send({
      title: "Awesome post",
      body: "Awesome post body",
    });
    expect(response.statusCode).toBe(200);
  });

  test("creating new post when either of the data is not provided", async () => {
    const response = await supertest.agent(app).post("/post").send({
      title: "Awesome post",
    });
    expect(response.statusCode).toBe(400);
  });

  test("creating new post when no data is not provided", async () => {
    const response = await supertest.agent(app).post("/post").send();
    expect(response.statusCode).toBe(400);
  });
});
Enter fullscreen mode Exit fullscreen mode

Running Test

Run test using following command:

npm run test
Enter fullscreen mode Exit fullscreen mode

supertest and jest output

If using VS Code extensions like jest and jest runner then it’ll do the work for you.

supertest and jest output

And this is how we can easily test API endpoints. 💪

SpongeBob with rainbow

Top comments (0)