我有一些代码如下:
var request = require('request');
function Service(){
this._config = require('../path/to/config.json');
}
Service.prototype.doThing = function(){
return new Promise(function(resolve, reject){
request.post(url, {payload}, function(error, response, body){
//handle response
resolve(true);
}).on('error', function(err){
//handle errors
resolve(false);
});
});
}
我正在尝试测试运行错误的块,但由于承诺而遇到困难。我正在使用mocha进行测试运行,使用sinon进行存根。我能够存根请求,以便我可以计算on方法被调用的次数,但是包含的Promise永远不会解析。
有一些软件包可以与sinon一起处理promises(我已经尝试过sinon-as-promise和sinon-stub-promise),但我必须存根整个doThing方法才能正确解析。我将非常感谢有关测试此代码的替代方法的任何输入或可能更容易测试的替代代码结构。
有问题的测试(挂起等待doThing承诺返回)如下:
context('when the server is unavailable', function(){
beforeEach(function() {
var onStub = sinon.stub();
requestStub = {post: function(){ return {on: onStub}}};
Service = proxyquire('path/to/service', {request: requestStub});
service = new Service();
});
it('should not set the auth key', function(){
return service.doThing().then(function(x){
return assert(onStub.calledOnce);
});
});
});
谢谢!
答案 0 :(得分:1)
总结显而易见的,您的问题是您不能控制request
对象,或者更确切地说是来自post
方法的响应。如果您可以控制,则可以使用doThing
方法测试所有不同的代码路径。
您有三种可能性来控制来自request
的响应:
request
库的内容。request.post
的存根(需要修改代码)require()
调用返回的对象替换为您控制的存根对象。这当然是你所做的。就个人而言,我会选择2,因为它不需要额外的框架,易于推理且易于实现。您可以参考this quite elaborate example,但您的案例中所需的代码很少。
无论如何,既然你已经选择了选项3,我可能会沿着那条路走下去:-)问题是你如何删除post
方法。有没有会打电话回电话?
我会将post
存根改为:
post: (url, options, cb) => {
cb(null, null, null); // will resolve your promise in the module
return { on: onStub };
}
当然,如果您稍后需要对值进行操作,那么传入回调的null
可能是其他内容。