Testing your Express.js Backend Server

lukekyl

Kyle Luke

Posted on February 3, 2021

Testing your Express.js Backend Server

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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
npm install supertest --save-dev
Enter fullscreen mode Exit fullscreen mode
npm install cross-env --save-dev
Enter fullscreen mode Exit fullscreen mode
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",
  }
Enter fullscreen mode Exit fullscreen mode

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/"
    ]
  },
...
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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')
  });

});
Enter fullscreen mode Exit fullscreen mode

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')
    });
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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!

💖 💪 🙅 🚩
lukekyl
Kyle Luke

Posted on February 3, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Testing your Express.js Backend Server