Mastering API Testing with Supertest, Express.js, and Jest
Introduction
Supertest
Working hand in hand with frameworks like Express.js
In this blog post, we will set up a basic Express app and write tests using Supertest and Jest
At first, the tests will be straight forward on validating the response status. Then, we will dive into asserting the response body and its values.
All code from today can be found remotely on this repo
Setting Up The Repository
Before we dive into writing our application and tests, we need to set up our repository. Here are the steps to do that:
# Create a new directory for your project mkdir demo-express-jest-supertest cd demo-express-jest-supertest # Initialize a new Node.js project pnpm init # Install necessary dependencies pnpm i express pnpm i -D jest supertest
Once our repository is set up, we can start writing our application and tests.
Crafting The Demo Express App
Let's build a simple Express.js application to demonstrate how we can test it using Supertest and Jest.
Firstly, create a new file app.js
at the root of the project directory using touch app.js
and add the following:
// app.js // 1. Require express const express = require("express"); // 2. Create the new express app instance for our API const app = express(); // 3. Define the route for the GET /greet endpoint app.get("/greet", (req, res) => { const name = req.query.name || "World"; res.json({ message: `Hello, ${name}!` }); }); // 4. Export the app for testing later module.exports = app;
In the above code, we add the following:
- We require the
express
module. - We create a new instance of the Express app.
- We define a route for the
GET /greet
endpoint that returns a JSON response with amessage
property. - We export the app instance for testing later.
This will set up our baseline Express app, but it does not start the server. If we want to do that, we need to create a new file server.js
at the root of the project directory using touch server.js
and add the following:
// 1. Import our app from the app.js file const app = require("./app"); // 2. Start the server on port 3000 app.listen(3000, () => { console.log("Server is running on port 3000"); });
At this point, we could run our app using node server.js
on the terminal and test it using a tool like curl
or Postman.
To confirm, we can run curl http://localhost:3000/greet
on the terminal and get the following response:
curl http://localhost:3000/greet # {"message":"Hello, World!"}
Running curl http://localhost:3000/greet?name=John
on the terminal will return the following response:
curl http://localhost:3000/greet?name=John # {"message":"Hello, John!"}
At this point, we are ready to write our first tests. You can stop running the server in the first terminal using Ctrl + C
and move onto the next section.
Writing Tests with Supertest and Jest
Now that we have our Express app ready, it's time to write some tests to assert the response and value of the body.
First, create a new file app.test.js
at the root of the project directory using touch app.test.js
and add the following:
// app.test.js const request = require("supertest"); const app = require("./app"); describe("GET /greet", () => { it("should greet the world when no name is provided", async () => { const res = await request(app) .get("/greet") .expect("Content-Type", /json/) .expect(200); expect(res.body.message).toBe("Hello, World!"); }); it("should greet the user when a name is provided", async () => { const res = await request(app) .get("/greet?name=John") .expect("Content-Type", /json/) .expect(200); expect(res.body.message).toBe("Hello, John!"); }); });
In the code above, we are using Supertest to send HTTP requests to our app and Jest to write and run the test assertions.
The expect
method is used to check the response status and headers, while Jest's expect
function is used to assert the value of the response body.
Running The Tests
To run the tests, let's jump into the package.json
file that was initialized with pnpm init
and update the scripts > test
property to the following:
{ "scripts": { "test": "jest" } }
You can now run pnpm
test to run the tests. You should see the following output:
$ pnpm test > demo-express-jest-supertest@1.0.0 test /Users/dennisokeeffe/code/projects/demo-express-jest-supertest > jest Determining test su PASS ./app.test.js GET /greet ✓ should greet the world when no name is provided (45 ms) ✓ should greet the user when a name is provided (14 ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total
Our tests are passing, happy days!
Conclusion
This setup provides a solid foundation to further explore and understand the capabilities of Supertest, Express.js, and Jest in the realm of API testing. As you delve deeper, you'll discover the power and flexibility this combination offers to ensure the reliability and correctness of your APIs.
We demonstrated how to set up a basic Express.js application and write tests using Supertest and Jest. We started with simple tests to assert the response status and then moved onto asserting the response body and its values.
Supertest can be used for far more things than I demonstrated in today's post. It is also great for asserting headers, cookies, and more. I encourage you to check out the Supertest documentation
References and Further Reading
Photo credit: pecarrolo

Dennis O'Keeffe
Melbourne, Australia
1,200+ PEOPLE ALREADY JOINED ❤️️
Get fresh posts + news direct to your inbox.
No spam. We only send you relevant content.
Mastering API Testing with Supertest, Express.js, and Jest
Introduction