In this section, we will learn how to test the REST API using a library called supertest and jest.
The tests can be done by following these steps:
- Start a test server
- Invoke a handler by making an HTTP request to a specific API endpoint
- Assert based on the expected response status code and body
We can use supertest for steps 1 and 2, and Jest for running the tests and making assertions.
This demo below shows how to write Express API tests using supertest and Jest:
https://github.com/thoughtworks-jumpstart/express-pizza-app-with-tests
If you need to restart your Express-based application before each test case (e.g. so that your test cases do not interfere with each other), you can follow the steps in this tutorial
There are 3 steps in the trick:
- Use a library called really-need so that
require
does not reuse cached modules - Start a new server before each test case
- Stop the server after each test case
The type of tests we write here with supertest is called integration test.
Integration tests, as the name suggests, tests that the different layers of your application (e.g. app, router, request handlers, any middleware, models and database) works as expected when integrated together.
In contrast, there is another type of tests, called Unit Test, which focus on testing a module/class/function works alone.
- Fork and clone https://github.com/thoughtworks-jumpstart/express-books-api
- Go into directory:
cd express-books-api
- Install dependencies:
npm install
- Smoke test:
npm start
and you should see a valid response on http://localhost:3000
Your task is to implement tests for the books router without changing the behaviour in routes/books.js
Steps:
- Create a test directory:
mkdir -p tests/integration-tests
- Create a test file:
touch tests/integration-tests/books.test.js
- Install test dependencies:
npm install jest --save-dev
npm install supertest --save-dev
- One by one, write a test for each route handler. An example for GET /books is written below
const app = require("../../app");
const request = require("supertest");
describe("routes/books", () => {
it("GET /books should return a list of books", () => {
return request(app)
.get("/books")
.then(response => {
expect(response.status).toEqual(200);
expect(response.body.message).toEqual("Whatever the route handler returns in the message field");
});
});
})
- Testing asynchronous functions with
jest
- Using
supertest
to make http requests supertest
's documentation are almost non-existent, so we can also refer tosuperagent
. Many ofsupertest
's methods (e.g..get()
,.post()
,.send()
, etc) come fromsuperagent
- Unit testing express routers