在节点中测试失败的请求 [英] Testing failed requests in node

查看:75
本文介绍了在节点中测试失败的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些如下所示的代码:

I have some code that looks like the following:

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 永远不会解析.

I'm trying to test the block that runs on error, but having difficulty because of the promise. I'm using mocha for test running and sinon for stubbing. I'm able to stub request so that I can count the number of times the on method is called, but the containing Promise never resolves.

有一些包可以与 sinon 一起处理承诺(我尝试过 sinon-as-promised 和 sinon-stub-promise),但我必须存根整个 doThing 方法才能正确解析.我将不胜感激任何有关测试此代码或可能更易于测试的替代代码结构的正确方法的输入.

There are some packages that work with sinon to handle promises (I've tried sinon-as-promised and sinon-stub-promise), but I have to stub the entire doThing method in order for it to resolve properly. I would appreciate any input on the propper way to test this code or alternate code structures that may be easier to test.

有问题的测试(挂起等待 doThing 承诺返回)如下:

The test in question (that hangs waiting for the doThing promise to return) is below:

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 对象,或者更确切地说是它的响应<代码>发布方法.如果您可以控制,您将能够在您的 doThing 方法中测试所有不同的代码路径.

To sum up the obvious, your problem here is that you do not control the request object, or rather the response from its post method. If you can control that you will be able to test all the different code paths in your doThing method.

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

You have three possibilities for controlling the response from request:

  1. 剔除网络层(使用类似Nock) 这样您就可以控制 HTTP 层将哪些内容移交给 request 库.
  2. 使用依赖注入注入一个可以代替request.post的存根(需要修改代码)
  3. 使用链接接缝,将require() 调用返回的对象替换为您控制的存根对象.这当然是你所做的.
  1. Stub out the network layer (using something like Nock) so you can control what the HTTP layer is handing over to the request library.
  2. Use dependency injection to inject a stub that can be used in place of request.post (will require a code modification)
  3. Use a link seam to that will substitute the object returned from require() calls with a stub object you control. This is of course what you have done.

就我个人而言,我会选择选项 2,因为它不需要额外的框架,易于推理且易于实现.您可以参考这个非常详细的示例,但您的情况所需的代码很少.

Personally, I would have gone for option 2 since that requires no extra framework, is easy to reason about and is easy to implement. You can refer to this quite elaborate example, but the code needed in your case is minimal.

无论如何,既然您选择了选项 3,我不妨沿着这条路线走下去 :-) 问题在于您如何消除 post 方法.会不会打电话给你的回电?

Anyway, since you have chosen option 3 I might as well go down that route :-) The problem is how you stubbed out the post method. Have will that ever call your callback?

我会将 post 存根更改为如下所示:

I would change the post stub to something like this:

post: (url, options, cb) => { 
  cb(null, null, null); // will resolve your promise in the module
  return { on: onStub }; 
}

当然,如果您稍后需要对值执行某些操作,则传递到您的回调中的 null 可以是其他内容.

Of course, the nulls passed into your callback can be something else should you need to do something with the values later on.

这篇关于在节点中测试失败的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆