简体   繁体   中英

how do I stub the cloud api using mocha test sinon?

I am working on mocha unit test. there I call the api with req, res, next. It goes there then inside the method it calls another api that is a cloud api. gets a record. returns the record. Here cloud api calls real api. i need to stub that api. pasted the code here. please give me a suggestion. I am using sinon stub.

controller.js

module.exports.getAllRooms = (req, res) => {
  // console.log('test mock called ----> > > > ');
  var selector = req.params.selector;
  options.method = 'GET';
  options.url = lifxApiProps.baseUrl + selector;
  options.body = {};
  // console.log('options ---> ', options);
  http.get(options, (error, response, body) => {
    if (error) return Error(error);
    findDups = _.map(body, 'group');
    return res.send(_.uniqBy(findDups, 'name'));
  });
};

test.js:

describe('#getAllRooms', () => {
      beforeEach(() => {
        req.params = { selector: 'all' };
        req.body = {};
      });
      it('should call lifx api ', (done) => {
        const callbackRes = [
          {
            id: 'd073d5127219',
            uuid: '024008b0-af2d-4170-827d-b0288088c5c3',
            label: 'LIFX Bulb 127219',
            connected: true,
            power: 'on',
            color: {
              hue: 240,
              saturation: 1,
              kelvin: 3500,
            },
            brightness: 0.998794537270161,
            group: {
              id: '36b47494e70bb82e44e6a7804f5c6300',
              name: 'Jaime Office',
            },
            location: {
              id: '6f2971162984b79fe437dd5f1f73579e',
              name: 'Knocki HQ',
            },
            product: {
              name: 'Color 1000 BR30',
              identifier: 'lifx_color_br30',
              company: 'LIFX',
              capabilities: {
                has_color: true,
                has_variable_color_temp: true,
                has_ir: false,
                has_multizone: false,
              },
            },
            last_seen: '2017-08-03T06:04:41Z',
            seconds_since_seen: 0,
          },
        ];
        sandbox.stub(http, 'get', (options, callback) => callback(null, null, callbackRes));
        res.send = (result) => {
          console.info('response of get all rooms ----> ', result);
          expect(result).to.exist;
          done();
        };
        controller.getAllRooms(req, res, next);
      });
    });

stub is not working here: error

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

Here is the unit test solution:

controller.js :

const _ = require("lodash");
const http = require("http");
const lifxApiProps = { baseUrl: "http://google.com" };

module.exports.getAllRooms = (req, res) => {
  const options = {};
  var selector = req.params.selector;
  options.method = "GET";
  options.url = lifxApiProps.baseUrl + selector;
  options.body = {};
  http.get(options, (error, response, body) => {
    if (error) return Error(error);
    findDups = _.map(body, "group");
    return res.send(_.uniqBy(findDups, "name"));
  });
};

controller.test.js :

const { getAllRooms } = require("./controller");
const http = require("http");
const sinon = require("sinon");

describe("getAllRooms", () => {
  afterEach(() => {
    sinon.restore();
  });
  it("should send response", () => {
    const getStub = sinon.stub(http, "get");
    const sendStub = sinon.stub();
    const mReq = { params: { selector: "/a" } };
    const mRes = { send: sendStub };
    getAllRooms(mReq, mRes);
    const mBody = [{ group: "google" }, { group: "reddit" }];
    getStub.yield(null, {}, mBody);
    sinon.assert.calledWith(
      getStub,
      {
        method: "GET",
        url: "http://google.com/a",
        body: {}
      },
      sinon.match.func
    );
    sinon.assert.calledWith(sendStub, ["google"]);
  });

  it("should handle error", () => {
    const getStub = sinon.stub(http, "get");
    const sendStub = sinon.stub();
    const mReq = { params: { selector: "/a" } };
    const mRes = { send: sendStub };
    getAllRooms(mReq, mRes);
    const mError = new Error("network error");
    getStub.yield(mError, {}, null);
    sinon.assert.calledWith(
      getStub,
      {
        method: "GET",
        url: "http://google.com/a",
        body: {}
      },
      sinon.match.func
    );
    sinon.assert.notCalled(sendStub);
  });
});

Unit test result with 100% coverage:

 getAllRooms
    ✓ should send response
    ✓ should handle error


  2 passing (15ms)

--------------------|----------|----------|----------|----------|-------------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files           |      100 |      100 |      100 |      100 |                   |
 controller.js      |      100 |      100 |      100 |      100 |                   |
 controller.test.js |      100 |      100 |      100 |      100 |                   |
--------------------|----------|----------|----------|----------|-------------------|

Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/45481923

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