javascript - 如何模拟回调函数以进行测试,该函数位于另一个函数的参数中
问题描述
我的要求是模拟另一个函数的参数内部的回调函数以进行单元测试。
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()
})
})
})
解决方案
这是单元测试解决方案:
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
推荐阅读
- windows-10 - Net.Framework 4.7.2 和 Windows 10 中的长路径支持
- compiler-errors - symbol expected in first line of libre office type definition
- html - 如何更改主体颜色但不影响 div?
- c# - 检查类型是否派生自具有多个通用参数的接口
- ruby-on-rails - 将 aws elastic beanstalk ruby on rails 应用程序连接到 aws postgres rds
- swift - Swift Switch 语句无法匹配字符串:这可能是什么原因?
- r - 在 R 中,如何读取索引向量?
- laravel - Laravel Passport 自定义用户提供者:提供者选项不存在
- css - 带有反应的字体真棒 5.13.0
- python - Python:我想创建一个循环来计算要保存在文件夹中的附件