2016-02-23 5 views
11

я должен проверить на наличие ошибок сервера (Express) в приемо-сдаточных испытаний, которые не могут (или не должны) быть отправлены с ответом, напримерошибки Тестирование Экспресс с Mocha и Supertest

Error: Can't set headers after they are sent.

Ловля ошибку с обработчиком ошибок и отвечая кодом 5XX, предоставит ценную информацию здесь, но проблема в том, что заголовки уже отправлены.

Такие ошибки могут быть некритичными и трудно различимыми, и обычно они вычисляются из журналов.

ФПЭ

it('should send 200', function (done) { 
    request(app).get('/').expect(200, done); 
}); 

и испытанного приложение

app.get('/', function (req, res, next) { 
    res.sendStatus(200); 
    next(); 
}); 

app.use(function (req, res) { 
    res.sendStatus(200); 
}); 

Что является наиболее подходящим способом общения между экспрессом app экземпляром и запросом тестированием библиотеки (т.е. Supertest) в подобных случаях?

Вопрос не ограничивается Supertest. Если есть пакеты, которые могут решить проблему, которую Supertest не может, они также могут рассматриваться.

+0

Что касается 'res.status (500) .send()' – walkerrandophsmith

+0

@WalkerRandolphSmith Заголовки уже отправлены первым res.sendStatus, это приведет к ошибке «Невозможно установить заголовки после их отправки». – estus

+0

Ahh Думаю, теперь я понимаю. – walkerrandophsmith

ответ

-2

Я сделал это, используя HAPI вместо Express, но я решил ту же проблему. Я использовал внешнюю библиотеку для вызова (например, запрос-обещание), и это сработало. Поймать ошибку в ответе на запрос-обещание.

+1

Я не уверен, что вы имеете в виду. В примере request-prom не может уловить ошибку, потому что в самом ответе нет ошибки - это 200. См. Комментарии, это уже обсуждалось там. – estus

1

Попробуйте просто установить код состояния, не отправляя его, и не отправляйте его дважды, используя ошибку res.status().

Как express documentation говорят, что

Sets the HTTP status for the response. It is a chainable alias of Node’s response.statusCode .

ИМХО, если вы хотите обнаружить его в (E2E) тестирования инструмента от конца до конца, как supertest (или Селен) вы должны обрабатывать экспресс-ошибку и отправлять правильный результат (500 сообщений о состоянии, некоторое сообщение ...), чтобы разрешить его обнаружение.

Или используйте вместо этого unit test, чтобы проверить, что функция контроллера не вызывает никаких ошибок, используя chai или собственное утверждение.

+0

И в результате ответ не будет отправлен. Вопрос заключается в обнаружении ошибки, а не в изменении кода приложения. – estus

+0

Да, извините. Я только что обновил ответ. – Dario

+0

Спасибо. Что касается ошибки 500, проблема остается прежней - после отправки ответа 200 она не может быть изменена на 500. И модульные тесты должны выполняться изолированно от других устройств. Это означает, что тест может проходить для конкретного промежуточного программного обеспечения, но приведет к ошибке при укладке нескольких промежуточных элементов. – estus

1

Я ответил на аналогичный вопрос here. «Невозможно установить заголовки после того, как они были установлены» ошибка должна быть вызвана выражением как необработанное исключение. Таким образом, вы должны иметь возможность получить доступ к нему через событие unhandledException, которое вызвано процессом.

Однако, это намного сложнее из-за времени. Ваш тестовый пример ожидает функция и done функция будет поставлена ​​в очередь для обработки в цикле событий на галочке сразу после первого вызова res.statusCode. К сожалению, следующий вызов для res.statusCode может произойти через неопределенный промежуток времени после этого. Например, что, если второй обработчик маршрута вызвал действительно медленный веб-сервис или db, а затем вызвал res.statusCode.

Имея это в виду, ваши варианты довольно сложны. Метод грубой силы заключается в том, чтобы ждать в вашем тестовом коде определенное время, а затем проверить.Он эффективен, но медленен и не детерминирован, что приведет к тому, что ваш тест будет шелушащимся.

Другой вариант - проверить любой код инструментария, который может иметься в экспресс-режиме. Если у вас есть код в выражении, который содержит показатели количества вызовов процесса для разных обработчиков маршрутов, вы можете подвергнуть эти показатели вашему тестовому коду. Тогда одно из ваших условий для завершения теста состоит в том, что все показатели для вызовов технологического маршрута равны 0. Второй вариант позволит вам писать детерминированные тесты и быть намного быстрее, потому что вы можете опросить показатели.

Окончательный вариант заключается в том, чтобы обрабатывать этот тестовый пример посредством модульных испытаний. Это, вероятно, лучшее решение, потому что оно будет детерминированным и не потребует каких-либо опросов. Однако недостатком является то, что вам нужно знать, что обе ваши функции вызываются по порядку, что приводит к тому, что вы пытаетесь воссоздать в своем тестовом коде логику, выражающую использование для вызова обработчиков маршрутов.

Смежные вопросы