Как проверить ошибку в запросе с помощью Nock?

Я хочу проверить ошибку в возврате запроса. Я использую нок в своих тестах, как заставить Nock вызывать ошибку? Я хочу достичь 100% -ного охвата тестирования и вам нужно проверить ветвь err для этого

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

Никогда не входите в ветвь if err. Даже если hit err является допустимым ответом, моя строка Nock в тесте выглядит так:

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

изменить благодаря некоторым комментариям:

  • Я пытаюсь высмеять ошибку в запросе. Из руководства node: https://nodejs.org/api/http.html#http_http_request_options_callback Если во время запроса встречается какая-либо ошибка (будь то с разрешением DNS, ошибками уровня TCP или фактическими ошибками разбора HTTP), на возвращенный объект запроса выдается событие "ошибка"
  • Код ошибки (например, 4xx) не определяет переменную err. Я пытаюсь точно высмеять это, независимо от ошибки, которая определяет переменную err и оценивается как true

Ответ 1

Использовать responseWithError. Из документов:

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

Ответ 2

Когда вы инициализируете запрос 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, и запрос увидит наши изменения. Хитрость заключается в попытке обезвреживать метод 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(), чтобы ваши будущие тесты не затрагивались вашими изменения.

Ответ 3

Похоже, вы ищете исключение по запросу 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
}

Ответ 4

Я знаю, что несколько лет спустя, но искал это и не мог найти его, возможно, он спасет время.

Я разрешил это, сделав запрос http://errorhost или мог быть чем угодно в этих строках.