Тестирование ошибок Express с помощью Mocha и Supertest

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

Ошибка: не удается установить заголовки после их отправки.

Попадание ошибки с обработчиком ошибок и ответ с кодом 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);
});

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

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

Ответ 1

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

Как выразить документацию, скажите

Устанавливает статус HTTP для ответа. Это скрепляемый псевдоним Node s response.statusCode.

IMHO, если вы хотите обнаружить его в инструменте тестирования сквозного (E2E), например supertest (или Selenium), вам нужно обработать экспресс-ошибку и отправить правильный результат ( 500, некоторое сообщение...), чтобы обнаружить его.

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

Ответ 2

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

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

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

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

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

Ответ 3

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