简体   繁体   中英

Node.js axios unit testing using Mocha, sinon and chai

I have node.js component name controller.js which have a function that calls api service using axios with options and it also have catch function for error handling. I am not able to stub axios function so as to cover it by unit testing.

Below is controller.js component.

const axios = require('axios');
export.getData = function(req, res, next) {
  try {
     const options = {
            method: 'GET',
            headers: headers,
            url,
            params: queryParams
     };  
     axios(options).then(function (response) {
            res.json(response.data);
        })
            .catch(function (error) {
                if (error && error.response) {
                    if (error.response.status === 401) {
                        res.status(500).send({ error: true, message: 'There seems to be an issue, please try after sometime' });                   
                    }
                 }
             });
  }
}

below is my controller.test.js

const chai = require('chai');
const assert = chai.assert;
const axios = require('axios');
const sinon = require('sinon');
const controller = require('../controllersr');

describe("controller API testing", () => {

it("should call getMarketId function and return status 200 on success", function (done) {
        const req = { };
        const res =  { json: {greet: "hello"}, status: 200};
        var mockStub = sinon.stub(axios, 'get').resolves(res);
        controller.getData(req, res);
        assert.equal(res.status, 200);
        mockStub.restore();
        done();
    });

});

Here, I am not able to stub axios funtion and catch function for error handling. And thus unable to cover the code for axios success and catch function in NYC. Please help..

First, You can't use try...catch statement to catch asynchronous code, if you want to do so, you need to use async/await to wait for the promise to be resolved or rejected. Besides, since you already caught the axios exception and didn't re-throw it, you don't need to try...catch .

Second, you are trying to stub axios function which is a standalone function imported from axios module. Sinon does NOT support that. You need to use Link Seams , so we will be using proxyquire to construct our seams.

Eg

controller.js :

const axios = require('axios');

exports.getData = function (req, res, next) {
  const options = {
    method: 'GET',
    headers: headers,
    url,
    params: queryParams,
  };
  axios(options)
    .then(function (response) {
      res.json(response.data);
    })
    .catch(function (error) {
      if (error && error.response) {
        if (error.response.status === 401) {
          res.status(500).send({ error: true, message: 'There seems to be an issue, please try after sometime' });
        }
      }
    });
};

controller.test.js :

const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('controller API testing', () => {
  it('should call getMarketId function and return status 200 on success', async () => {
    const req = {};
    const res = { json: sinon.stub(), status: 200 };
    const axiosStub = sinon.stub().resolves({ data: { greet: 'hello' } });
    const controller = proxyquire('./controller', {
      axios: axiosStub,
    });
    await controller.getData(req, res);
    sinon.assert.calledWithExactly(axiosStub, {
      method: 'GET',
      headers: {},
      url: 'http://localhost:3000/api',
      params: {},
    });
    sinon.assert.calledWithExactly(res.json, { greet: 'hello' });
  });
});

unit test result:

  controller API testing
    ✓ should call getMarketId function and return status 200 on success (1306ms)


  1 passing (1s)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |    62.5 |        0 |   66.67 |    62.5 |                   
 controller.js |    62.5 |        0 |   66.67 |    62.5 | 15-17             
---------------|---------|----------|---------|---------|-------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM