Languages
[Edit]
EN

JavaScript - express server Rest API mock with supertest and Jest

7 points
Created by:
Root-ssh
93540

In this article, we would like to show how to test Rest API using mocked modules with supertest library and Jest testing framework in JavaScript.

Quick solution:

const supertest = require('supertest')

it('GET /backend/path/to test', async () => {
    jest.resetModules();
    jest.doMock('../path/to/someServerModule', () => {
        // ../path/to/someServerModule mock used by ./path/to/my/server
        return {
            // someServerModule logic here ...
        };
    });
    // it is necessary to reload ./path/to/my/server module after mocks are defined
    const app = require('./path/to/my/server');
    const requester = supertest(app);
    const response = await requester.get('/backend/path/to'); // by ./path/to/my/server
    // response.body
});

Note: check GitHub repository.

Project details

Project structure: 

.
ÔöťÔöÇÔöÇ node_modules
ÔöťÔöÇÔöÇ package.json
ÔöťÔöÇÔöÇ package-lock.json
ÔööÔöÇÔöÇ src
    ÔöťÔöÇÔöÇ db.js
    ÔöťÔöÇÔöÇ index.js
    ÔöťÔöÇÔöÇ server.js
    ÔööÔöÇÔöÇ test
        ÔööÔöÇÔöÇ index.test.js

src/test/index.test.js file:

const supertest = require('supertest');

const createRequester = () => {
    // it is necessary to reload ../server module after mocks are defined
    const app = require('../server');
    return supertest(app);
};

describe('users api', () => {
    // always we want to use default defined modules as initial state
    beforeEach(() => jest.resetModules());

    it('getting users', async () => {
        jest.doMock('../db', () => {
            // ../db mock
            return {
                getUsers: () => ['mocked john', 'mocked ann', 'mocked matt']
            };
        });
        // we need to create requester after mock is defined
        const requester = createRequester();
        const users = await requester.get('/backend/users');
        expect(users.body[0]).toBe('mocked john');
        expect(users.body[1]).toBe('mocked ann');
        expect(users.body[2]).toBe('mocked matt');
    });
})

src/db.js file: <--- this module was reloaded in the test with mock

exports.getUsers = () => ['john', 'ann', 'matt'];

src/server.js file:

const express = require('express');
const db = require('./db');

const app = express();

app.get('/backend/users', async (req, res) => {
    const users = db.getUsers()
    res.json(users);
});

module.exports = app;

src/index.js file:

const app = require('./server');

app.listen(3000);

package.json file:

{
  "name": "jest-test",
  "version": "1.0.0",
  "description": "",
  "main": "src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "jest": "^26.6.3",
    "supertest": "^6.1.3"
  }
}

Running tests

Run the following command indicating test name:

node 'node_modules/.bin/jest' 'src/test/index.test.js' -t 'some feature'

Note: to install Jest, run in project directory: npm install --save-dev jest.

Example output:

 PASS  src/test/index.test.js
  users api
    Ôťô getting users (2546 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.374 s, estimated 30 s
Ran all test suites matching /\/home\/john\/Desktop\/jest-test\/src\/test\/index.test.js/i with tests matching "users api".
Waiting for the debugger to disconnect...

Running server

In this section, we would like to show when server is run in production mode.

Execute in the command line:

node src/index.js
Server run in production mode.
Server run in production mode.
Native Advertising
­čÜÇ
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

ÔŁĄ´ŞĆ­čĺ╗ ­čÖé

Join