如何用Nock测试请求中的错误?

coo*_*xeo 17 node.js nock

我想在请求返回中测试错误.我在测试中使用nock,如何强迫Nock引发错误?我想实现100%的测试覆盖率,并且需要测试错误的分支

request('/foo', function(err, res) {
  if(err) console.log('boom!');
});
Run Code Online (Sandbox Code Playgroud)

永远不要进入if err分支.即使命中错误是一个有效的响应,我的测试中的Nock行看起来像这样

nock('http://localhost:3000').get('/foo').reply(400);
Run Code Online (Sandbox Code Playgroud)

编辑: 感谢您的一些评论:

  • 我正在尝试模拟请求中的错误.从节点手册:https : //nodejs.org/api/http.html#http_http_request_options_callback 如果在请求期间遇到任何错误(具有DNS解析,TCP级别错误或实际的HTTP解析错误),则会出现"错误"事件在返回的请求对象上发出
  • 错误代码(例如4xx)未定义错误变量.我试图模仿那个,无论定义错误变量的错误和评估为真

小智 29

使用replyWithError.来自文档:

    nock('http://www.google.com')
   .get('/cat-poems')
   .replyWithError('something awful happened');
Run Code Online (Sandbox Code Playgroud)


Rob*_*ann 5

初始化http(s)请求时request(url, callback),它返回一个事件发射器实例(以及一些自定义属性/方法).

只要你能够掌握这个对象(这可能需要一些重构或者甚至可能不适合你),你可以使这个发射器发出一个error事件,从而通过err发出错误来触发你的回调.

以下代码段演示了这一点.

'use strict';

// Just importing the module
var request = require('request')
// google is now an event emitter that we can emit from!
  , google = request('http://google.com', function (err, res) {
      console.log(err) // Guess what this will be...?
    })

// In the next tick, make the emitter emit an error event
// which will trigger the above callback with err being
// our Error object.
process.nextTick(function () {
  google.emit('error', new Error('test'))
})
Run Code Online (Sandbox Code Playgroud)

编辑

这种方法的问题在于,在大多数情况下,它需要一些重构.另一种方法利用了Node的本机模块在整个应用程序中被缓存和重用的事实,因此我们可以修改http模块,Request会看到我们的修改.诀窍在于修补http.request()方法并将自己的逻辑注入其中.

以下代码段演示了这一点.

'use strict';

// Just importing the module
var request = require('request')
  , http = require('http')
  , httpRequest = http.request

// Monkey-patch the http.request method with
// our implementation
http.request = function (opts, cb) {
  console.log('ping');
  // Call the original implementation of http.request()
  var req = httpRequest(opts, cb)

  // In next tick, simulate an error in the http module
  process.nextTick(function () {
    req.emit('error', new Error('you shall not pass!'))
    // Prevent Request from waiting for
    // this request to finish
    req.removeAllListeners('response')
    // Properly close the current request
    req.end()
  })

  // We must return this value to keep it
  // consistent with original implementation
  return req
}

request('http://google.com', function (err) {
  console.log(err) // Guess what this will be...?
})
Run Code Online (Sandbox Code Playgroud)

我怀疑Nock做了类似的事情(取代了http模块上的方法),所以我建议你在需要(也许还配置?)Nock 之后应用这个猴子补丁.

请注意,确保仅在请求正确的URL(检查opts对象)并恢复原始http.request()实现时才发出错误,以便将来的测试不受更改影响,这将是您的任务.


小智 0

看起来您正在寻找 nock 请求的异常,这也许可以帮助您:

var nock = require('nock');
var google = nock('http://google.com')
               .get('/')
               .reply(200, 'Hello from Google!');

try{
  google.done();
}
catch (e) {
  console.log('boom! -> ' + e); // pass exception object to error handler
}
Run Code Online (Sandbox Code Playgroud)