Recently I have been learning about Node, and building a backend API server with Express. Express.js allows for use of the MVC pattern similarly to Ruby on Rails for building a RESTful CRUD API (making a good learning transition for me). While learning how to implement all of the CRUD pieces with Express, I wanted to test the functionality to verify things were working properly. This blog post will explain how to test the CRUD functionality of routes in your Express backend API, with the use of Jest framework and SuperTest library.
Express Server
I am assuming that you have an Express server running for this article, but below is a simple sample app to get the tests within this article running (below I will share some additional articles on building an Express server). In the code below you will find two example GET
endpoints, along with some sample code to give you an idea of what your route might ACTUALLY look like when built out further.
// server.js
import express from 'express';
const app = express();
app.get('/users', function(req, res) {
res.json({ users: 'allUsers' });
// Real code from my application below
// model.User.findAll().then (users => {
// res.status(200).json({ users });
// }).catch(error=>{
// console.log(error)
// req.status(500).send(error)
// })
});
app.get('/users/3', function(req, res) {
res.json({ user: 'user3' });
// Real code from my application below
// const { id } = req.params;
// model.User.findOne({
// where: { id: Number(id) }
// }).then(user=>{
// res.status(200).json({ user });
// }).catch(error=>{
// console.log(error)
// req.status(500).send(error)
// })
});
export const server = app;
Looking through the above routes, we see two GET
requests: one for ALL users, and one for a SELECT user. Our tests will verify that each GET
request will return a status code 200
, have json
content type, and include the property we want to see returned (such as users
, or user3
).
Setting Up Jest & SuperTest
First and foremost, we have to set up the testing environment. Below are the steps to getting Jest and SuperTest up and running.
1. Installing Our Dependencies
npm install jest --save-dev
npm install supertest --save-dev
npm install cross-env --save-dev
2. Setting up the testing environment
To set up the testing environment, we need to adjust the package.json
folder in your Express application. The following settings allow you to run npm test
in the CLI, which will perform a reset of the test database, migrate and seed your database each time for accurate testing purposes.
- Note
NODE_ENV=test
being used to specify the test environment.
// package.json
"scripts": {
...
"test": "cross-env NODE_ENV=test jest --testTimeout=10000",
"pretest": "cross-env NODE_ENV=test npm run migrate:reset",
"migrate:reset": "npx sequelize-cli db:migrate:undo:all && npm run migrate",
"migrate": "npx sequelize-cli db:migrate && npx sequelize-cli db:seed:all",
}
We need Jest to ignore our ./node_modules
folder, so we also need to add this snippet of code to package.json
:
...
"jest": {
"testEnvironment": "node",
"coveragePathIgnorePatterns": [
"/node_modules/"
]
},
...
OK, now to try running a test with npm test
in the command line. Now that we have our testing environment up and running, we should be able to start writing our tests!
Writing Tests
We will be working in a new test.js
file, and our goal is to test the functionality of the two GET
requests above:
/users
and /users/3
.
Import
We first need to import some dependancies so we can test our Express server. These go at the top of our test.js
file.
//test.js
const server = require('../index.js');
const supertest = require('supertest');
const requestWithSupertest = supertest(server);
You will notice that we are using requestWithSupertest
, which links each test to the server.
Get all Users
The first thing we need is our initial describe
block which will house BOTH of our tests. In this test, we will be checking how the /user
GET route functions.
describe('User Endpoints', () => {
it('GET /user should show all users', async () => {
const res = await requestWithSupertest.get('/users');
expect(res.status).toEqual(200);
expect(res.type).toEqual(expect.stringContaining('json'));
expect(res.body).toHaveProperty('users')
});
});
In the code above, you notice we have added await
to requestWithSupertest.get('/users')
, because we are testing a promise that needs to be fulfilled before moving forward. We then expect to see a 200
status, json
content type, and for the response body to have the users
property. These three expectations fulfill what we wanted to test for in this route's functionality.
Get a User by ID
Ok, so we have our first test written. Now for the second test we will make a similar test, this time targeting the /users/3
route. This test is supposed to show how you can test for a GET route of a targeted user id. This test will also be placed within the same describe
block we defined above.
it('GET /user/:id should show a user', async () => {
const res = await requestWithSupertest.get('/users/3')
expect(res.statusCode).toEqual(200)
expect(res.body).toHaveProperty('user3')
});
Run the Tests
Awesome! We have written two tests to verify functionality of our two sample GET
routes. Now to run the tests in the command line:
npm test
You should see two passing tests in our test suite!
Conclusion
You now have the resources to add some testing to your Express API! Hopefully the above examples help you to gain some initial understanding on how to set up and test the functionality of your Express server! I wanted to expand my knowledge of testing Express backend API requests, and this is how I set up tests within my own application!
Some additional resources I have used to help me learn Express.js and how to test the server include
Node.js Rest APIs example with Express, Sequelize & MySQL by bezkoder
Building an Express API with Sequelize CLI and Unit Testing! by Bruno Galvao
How to test your Express.js backend with Jest and Supertest by Coderslang
Hopscotch.io - a tool to send server requests and see the responses
Has this article helped you get started with testing your Express server? Respond with comments or recommendations!
Top comments (1)
Thanks for sharing your insights on testing Express.js backend servers! It's always interesting to explore different perspectives on this topic. If anyone's looking to dive deeper into Express testing, I recently came across a comprehensive guide titled 'Express Testing: Getting Started Quickly With Examples.' It provides a step-by-step approach and practical examples to help you get up and running with Express testing efficiently. It could be a valuable resource for those interested in enhancing their testing practices.