在节点中testing失败的请求
我有一些如下所示的代码:
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); }); }); }
我试图testing运行错误的块,但由于承诺而有困难。 我正在使用摩卡进行testing运行,并使用了sinon进行testing。 我能够存根请求,以便我可以计算on方法被调用的次数,但是包含的Promise永远不会parsing。
有一些软件包可以和sinon一起处理promise(我已经尝试过sinon-promise和sinon-stub-promise),但是我必须存储整个doThing方法才能正确parsing。 我将不胜感激在任何方式来testing这个代码或替代的代码结构,可能更容易testing的input。
有问题的testing(等待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); }); }); });
谢谢!
总而言之,你的问题在于你不控制request
对象,或者说是对它的post
方法的响应。 如果你可以控制,你将能够在你的doThing
方法中testing所有不同的代码path。
您有三种可能性来控制来自request
的响应:
- 将networking层(使用像Nock这样的东西)留在networking层,这样就可以控制HTTP层传递给
request
库的内容。 - 使用dependency injection来注入一个可以代替
request.post
使用的存根(需要修改代码) - 使用一个链接接缝来代替从你要控制的存根
require()
stub)对象中调用require()
调用返回的对象。 这当然是你所做的。
就我个人而言,我会select2,因为这不需要额外的框架,很容易推理和易于实现。 你可以参考这个相当复杂的例子 ,但在你的情况下所需的代码是最小的。
无论如何,既然你已经select了选项3,我不妨去那条路:-)问题是你如何取消post
方法。 有永远打电话给你的callback?
我会改变post
存根这样的事情:
post: (url, options, cb) => { cb(null, null, null); // will resolve your promise in the module return { on: onStub }; }
当然,传递给你的callback函数的null
可能是其他值,你需要在后面的值上做些什么。