22

リクエストリターンでエラーをテストしたい。テストで nock を使用していますが、Nock にエラーを発生させるにはどうすればよいですか? 100% のテスト カバレッジを達成したいので、エラー ブランチをテストする必要があります。

request('/foo', function(err, res) {
  if(err) console.log('boom!');
});

if err ブランチには絶対に入らないでください。hit err が有効な応答であっても、テスト中の私の Nock 行は次のようになります

nock('http://localhost:3000').get('/foo').reply(400);

編集: コメントのおかげで:

  • リクエストのエラーをモックしようとしています。ノードのマニュアルから: https://nodejs.org/api/http.html#http_http_request_options_callback リクエスト中にエラーが発生した場合 (DNS 解決、TCP レベルのエラー、または実際の HTTP 解析エラーなど)、「エラー」イベントが発生します。返されたリクエスト オブジェクトで発行された
  • エラー コード (4xx など) は、err 変数を定義しません。err 変数を定義し、true と評価されるエラーが何であれ、それを正確にモックしようとしています。
4

4 に答える 4

38

replyWithError を使用します。ドキュメントから:

    nock('http://www.google.com')
   .get('/cat-poems')
   .replyWithError('something awful happened');
于 2015-05-06T07:09:55.303 に答える
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'))
})

編集

このアプローチの問題点は、ほとんどの場合、多少のリファクタリングが必要になることです。別のアプローチでは、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...?
})

Nockも似たようなこと ( httpモジュールのメソッドの置き換え) を行っているのではないかと思うので、Nockを必要とした (そしておそらく構成した?)後に、このモンキー パッチを適用することをお勧めします。

正しい URL が要求された場合 (オブジェクトを調べたopts場合) にのみエラーを発行することを確認し、元の実装を復元しhttp.request()て将来のテストが変更の影響を受けないようにすることは、ユーザーのタスクになることに注意してください。

于 2015-01-04T12:04:51.310 に答える