如何使用mocha test sinon存根云api?

时间:2017-08-03 10:42:23

标签: javascript unit-testing mocha sinon

我正在进行摩卡单元测试。在那里,我用req,res,next来调用api。然后它在那个方法内部调用另一个api是一个cloud api。得到一个记录。返回记录。云API在这里称为真正的api。我需要存根那个api。在这里粘贴代码。请给我一个建议。 我正在使用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);
      });
    });

存根在这里不起作用:错误

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

1 个答案:

答案 0 :(得分:0)

这是单元测试解决方案:

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

覆盖率100%的单元测试结果:

 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 |                   |
--------------------|----------|----------|----------|----------|-------------------|

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/45481923