javascript - 如何模拟回调函数以测试其位于另一个函数的参数内

标签 javascript node.js unit-testing mocha.js chai

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

 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 block 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()
    })
  })

})

最佳答案

这是单元测试解决方案:

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

关于javascript - 如何模拟回调函数以测试其位于另一个函数的参数内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56827977/

相关文章:

javascript - 具有最大数字索引的元素

node.js - NodeJS 性能问题

typescript - 如何使用 jest 和 TS 来模拟 EventSource(尝试了大部分模拟策略)

javascript - 如何在jsplumb中使用导出方法?

javascript - 在 html 中清除链接的 css 属性

javascript - 无法理解带有 "this"关键字的函数的行为

php - 如何在 NodeJS 的请求中对表单字段中的数组进行编码?

node.js - 如何在不终止进程的情况下停止 node.js 服务器?

unit-testing - OpenCover 的运行时间比 nunit-console 长得多

javascript - 如何测试用户界面小部件?