首页 文章

测试节点中的失败请求

提问于
浏览
2

我有一些代码如下所示:

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);
    });
  });
});

谢谢!

1 回答

  • 1

    总而言之,这里的问题是你不能控制 request 对象,或者更确切地说是来自 post 方法的响应 . 如果您可以控制,您将能够在 doThing 方法中测试所有不同的代码路径 .

    您有三种控制 request 响应的可能性:

    • 存档网络层(使用类似Nock的内容),这样您就可以控制HTTP层切换到 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 可能是其他内容 .

相关问题