首页 > 解决方案 > 如何模拟回调函数以进行测试,该函数位于另一个函数的参数中

问题描述

我的要求是模拟另一个函数的参数内部的回调函数以进行单元测试。

 var jwt = require("jsonwebtoken");
 var APICall = require('./requestFile');

 function Helper(){
 this.request = new APICall();
  }

 Helper.prototype.getData = function (done) {
    var headers = {
        'content-type': "application/json",
    };
    var _self = this;
    this.request.get(this.pub_URL, get_headers, function (err, res, body) {
        if (!err && res.statusCode === 200) {
            console.log("Got data: ", body);
            done(null, body);
        }
        else {
            console.log("Error occured while fetching data: " + err)
            done(err, null);
        }
    });
  }
 }

我想模拟 this.request.get() 作为参数调用的回调函数,以便我的测试可以覆盖 else 块 console.log("获取数据时发生错误:" + err)。

这是我的带有代码库的测试文件

const Helper = require('../Helper');
var APICall = require('../requestFile');

let hlp = new Helper();

describe('APP', function() {
  before(function() {
    let res = {
      statusCode: 500
    }
    let err = {
      message: 'errors present'
    };
    var get_headers = {
      'content-type': "application/json",
    };
    sinon.stub(APICall.prototype, 'get').callsFake(function(done) {
      done(err, res)
    })

  })

  after(function() {
    APIRequester.prototype.get.restore();
  });
  it('should tell errors when request gets called for', function(done) {

    hlp.getData(function(err, data) {
      expect(data).to.be.a('string')
      done()
    })
  })

})

标签: javascriptnode.jsunit-testingmocha.jschai

解决方案


这是单元测试解决方案:

helper.js

const APICall = require("./request");

function Helper() {
  this.request = new APICall();
  this.pub_URL = "https://github.com";
}

Helper.prototype.getData = function(done) {
  const headers = {
    "content-type": "application/json",
  };
  this.request.get(this.pub_URL, headers, function(err, res, body) {
    if (!err && res.statusCode === 200) {
      console.log("Got data: ", body);
      done(null, body);
    } else {
      console.log("Error occured while fetching data: " + err);
      done(err, null);
    }
  });
};

module.exports = Helper;

request.js

function APICall() {}
APICall.prototype.get = function(url, headers, callback) {};

module.exports = APICall;

helper.test.js

const APICall = require("./request");
const sinon = require("sinon");
const Helper = require("./helper");

describe("56827977", () => {
  afterEach(() => {
    sinon.restore();
  });
  it("should get data correctly", () => {
    const helper = new Helper();
    const mRes = { statusCode: 200 };
    const mBody = "fake data";
    sinon.stub(APICall.prototype, "get").yields(null, mRes, mBody);
    const callback = sinon.stub();
    helper.getData(callback);
    sinon.assert.calledWithExactly(
      APICall.prototype.get,
      "https://github.com",
      {
        "content-type": "application/json",
      },
      sinon.match.func,
    );
    sinon.assert.calledWithExactly(callback, null, "fake data");
  });

  it("should handle error", () => {
    const helper = new Helper();
    const mError = new Error("network error");
    sinon.stub(APICall.prototype, "get").yields(mError, null, null);
    const callback = sinon.stub();
    helper.getData(callback);
    sinon.assert.calledWithExactly(
      APICall.prototype.get,
      "https://github.com",
      {
        "content-type": "application/json",
      },
      sinon.match.func,
    );
    sinon.assert.calledWithExactly(callback, mError, null);
  });
});

带有覆盖率报告的单元测试结果:

  56827977
Got data:  fake data
    ✓ should get data correctly
Error occured while fetching data: Error: network error
    ✓ should handle error


  2 passing (10ms)

----------------|----------|----------|----------|----------|-------------------|
File            |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files       |      100 |      100 |    88.89 |      100 |                   |
 helper.js      |      100 |      100 |      100 |      100 |                   |
 helper.test.js |      100 |      100 |      100 |      100 |                   |
 request.js     |      100 |      100 |       50 |      100 |                   |
----------------|----------|----------|----------|----------|-------------------|

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


推荐阅读