Mock HTTP Request In Express Unit Testing

How to Mock HTTP Request In Express Unit Testing

In this tutorial, you’ll learn how to mock HTTP request in express unit testing. This tutorial assumes the reader to have basic understanding of Express web framework and JavaScript.

I’ll be using the source code from one of our previous tutorial on how to make REST API calls in express web app. I would recommend reading the tutorial on making API calls before going ahead with this tutorial.

Getting Started With Express

I’ll start by cloning the source code from REST API express tutorial.

// cloning the source code
git clone https://github.com/codehandbook/make-api-call-express mock-http

Navigate to the project directory and install the required dependencies.

cd mock-http
npm install

Point your browser to http://localhost:3000/ and you will have the application running.

Mock HTTP Request In Express Unit Testing

Inside the app.js file you have a route called /getAPIResponse which makes an HTTP request to an external API. While unit testing our application we’ll mock every external dependency. In this case the external dependency is the API call.

We’ll be using Mocha, a JavaScript test framework for writing unit test case for our express web app. From the official documentation,

Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.

Start by installing mocha using npm.

// install mocha
npm install --save-dev mocha

Once you have installed mocha create a folder called test. All the test cases will be written inside the test folder. Create a file called app.spec.js inside the test folder.

Inside app.spec.js import the app from app.js file. Here is the basic structure for writing a unit test case using Mocha.

describe('unit testing /getAPIResponse route', function() {
  describe('testing with a dummy json', function(){
    before(function(){
        
    })
    it('should return the expected json response', async function(){
        
    })
    after(function(){
        
    })
  })
});

As seen in the above code, we started by describing what we are unit testing. Inside the main describe one more describe has been defined to clarifying what the test details. Inside the before callback we can define things which are needed for unit test case called as set up. Inside the after callback function the tear down of the set up takes place. The test case is defined inside the it callback function.

We’ll be using the supertest module for testing HTTP call to route the /getAPIResponse. Install supertest using npm.

// install supertest using npm
npm install --save-dev supertest

For mocking the REST API call you’ll be using a node module called nock. Install nock using npm.

// install nock using npm
npm install --save-dev nock

Let’s start by mocking the REST API call. Inside the before function callback add the following nock.

before(function(){
    /*
        Mock API using nock for the REST API
        Endpoint. Any calls to URL https://jsonplaceholder.typicode.com
        will be intercepted by the fake_api nock  
    */
    let fake_api = nock('https://jsonplaceholder.typicode.com')
        .get('/todos/1')
        .reply(200, {_id: '123ABC',_rev: '946B7D1C' });
})

Any call to the REST API endpoint https://jsonplaceholder.typicode.com/todos/1 will be intercepted with the above response.

Using supertest make a call to the /getAPIResponse route.

it('should return the expected json response', async function(){
    let response = await supertest(app)
                .get('/getAPIResponse')
    /* Checking if the response has OK status code*/
    assert(response.statusCode, 200)
    /* Checking for the _id returned from the fake_api */
    assert(response.body._id, '123ABC')
})

Since the REST API call has been mocked, the response should return _id as returned from the mock. You can assert it using the assert module.

Here is how the app.spec.js file looks :

const assert = require('assert');
const nock = require('nock');
const supertest = require('supertest');
const express = require('express');
const app = require('../app')

describe('unit testing /getAPIResponse route', function() {
  describe('testing with a dummy json', function(){
    before(function(){
        /*
            Mock API using nock for the REST API
            Endpoint. Any calls to URL https://jsonplaceholder.typicode.com
            will be intercepted by the fake_api nock  
        */
        let fake_api = nock('https://jsonplaceholder.typicode.com')
                .get('/todos/1')
                .reply(200, {_id: '123ABC',_rev: '946B7D1C' });
    })
    it('should return the expected json response', async function(){
        let response = await supertest(app)
                    .get('/getAPIResponse')
        /* Checking if the response has OK status code*/
        assert(response.statusCode, 200)
        /* Checking for the _id returned from the fake_api */
        assert(response.body._id, '123ABC')
    })
    after(function(){
        /* Once the uni test case has executed, clean up the nock.
            Now calls to the URL https://jsonplaceholder.typicode.com
            won't be intercepted. 
        */
        nock.cleanAll();
    })
  })
});

Add the following script to the package.json file.

"scripts": {
    "test": "mocha --exit"
  }

Save the above changes and run the test script.

// run the unit test case
npm run test

You will have the following output :

ajay@ajay-HP-Notebook:~/mock-http$ npm run test

> getnode@1.0.0 test /home/ajay/mock-http
> mocha --exit



App listening on port 3000!
  unit testing /getAPIResponse route
    testing with a dummy json
      ✓ should return the expected json response (38ms)


  1 passing (69ms)

Wrapping It Up

Source code from this tutorial is available on GitHub. In this tutorial, you learnt how to Mock HTTP Request In Express Unit Testing. Do you know of any other way to mock HTTP request in express unit testing ? Let us know in the comments below.