我需要为以下代码编写单元测试用例。这些网址是外部api调用,因此我需要模拟这些。对于其余的测试用例,我使用了sinon。因此,只想在 sinon 中编写这些内容。
function 1 {
async.waterfall() {
function 2();
function 3();
}
}
function 2(callback) {
url2_1 = "/calculatorFunctionList"
request.get(url2_1,function (err, res, body) {
return callback("with some diff response")
})}
function 3(callback) {
url3_1 = "addition/values="+somevalue1
url3_2 = "addition/values="+somevalue2
request.get(url3_1,function (err, res, body) {
if(!err) {
request.get(url3_2, function (err, res, body) {
return callback("with some response")
})
}
})
}
我需要对这些请求进行存根。我怎样才能做到这一点?还有如何以及何时调用存根的恢复,以免与其他请求存根混淆?目前,两个存根都没有被嘲笑。
答案 0 :(得分:0)
Sinon-的核心(暂时忘了lolex
和nise
)-显式处理javascript函数的存根和监视。而已。它本身与模块加载器或Node 本身无关。
因此,它不知道如何连接到Node的模块加载器(require
)并自行解决依赖关系。对于一般情况,您有两种选择:
function setRequestModule(module){ request = module }
),这些注入点可用于提供Sinon存根。那是通常的情况,但是由于您要处理网络级别的存根,因此存在第三个选项,该选项与第二个选项有关,这涉及到挂接Node的http层并在其中设置伪造的请求和响应使用nock
。
这看起来像这样:
const nock = require('nock')
const scope = nock('https://api.github.com')
.get('/repos/atom/atom/license')
.reply(200, {
license: {
key: 'mit',
name: 'MIT License',
spdx_id: 'MIT',
url: 'https://api.github.com/licenses/mit',
node_id: 'MDc6TGljZW5zZTEz',
},
})
这是我通常会做的事情,但是由于您坚持只使用Sinon,因此您将获得第一个选择。
第一个选项的阐述:注入依赖项
您的函数2
和3
(无效的javascript标识符,btw)都依赖于模块request
及其方法get
来获得结果。为了能够控制request.get
返回的内容,您需要为您的模块提供request
的不同版本以供测试。这可以使用依赖注入来完成。
首先,我假设您的函数以request
模块的导入开始,这意味着前几行包含如下语句:
const request = require('request');
您需要更改此语句,以便可以替换request
常量,这意味着它现在看起来像这样:
let request = require('request');
为了能够控制您的依赖关系,您现在可以向导出添加新功能:
module.exports.setRequestModule = function (stub){
request = stub;
}
要在测试中使用此功能,则需要在测试中执行此操作:
const myModule = require('../src/my-module');
const myRequestStub = {};
myModule.setRequestModule(myRequestStub);
it('should return the expected response', () => {
const expectedOutput = "with some response";
myRequestStub.get = function (url, callback) {
callback(null, expectedOutput);
}
myModule.doSomething() ...
// do test
});
或者 您还可以在模块中暴露请求对象:
module.exports._request = request;
例如,您可以使用sinon
通过在测试中插入get
方法来对其进行检测。
const myModule = require('../src/my-module');
sinon.stub(myModule._request, 'get').callsFake( (url, cb) => cb("hello!") );