HTTP-тестирование узла Mocha - зависание сокета

Я пытаюсь научиться тестировать с помощью node, для этого я использую фреймворк Mocha.

Я пытаюсь сделать запрос на получение экспресс-сервера, выполняя расчет двух чисел и возвращая его в виде структурированного объекта {result: sum}.

Однако я получаю UnhandledPromiseRejectionWarning с причиной: зависание сокета. Я провел некоторое исследование и на данный момент пришел к выводу, что ошибка возникает на сервере, когда клиент перестает слушать ответ на запрос, отправленный до того, как сервер отправит свой ответ. (если не так, я бы не возражал против некоторых пояснений).

Это мой тест Мокко:

const expect = require("chai").expect
const PORT = require("../server").PORT
const app = require("../server").app
const fetch = require("node-fetch")

const BASE_URL = `https://localhost:${PORT}/api/calc/`
let httpServer;
describe("testing endpoints for calculator Rest API", function () {

    before("starting the server..", function(done) {
        httpServer = app.listen(PORT)
        console.info("server is started")
        done()
    })

     describe("testing the add endpoint", function(){
         console.info("testing the API now!")
         it("add endpoints result should evaluate to 10", function(){
            fetch(`${BASE_URL}add/5/5`)
            .then(response => expect(response.result).to.be(10))
         })
     })
     after("shutting down the server..", function(){
        httpServer.close()  
     })

})

и это моя трассировка стека:

jonas@jonas:~/Desktop/testdemo1$ mocha
testing the API now!


  testing endpoints for calculator Rest API
starting server..
server started
    testing the add endpoint
      ✓ add endpoints result should evaluate to 10
(node:1949) UnhandledPromiseRejectionWarning: FetchError: request to https://localhost:1234/api/calc/add/5/5 failed, reason: socket hang up
    at ClientRequest.<anonymous> (/home/jonas/Desktop/testdemo1/node_modules/node-fetch/lib/index.js:1444:11)
    at emitOne (events.js:116:13)
    at ClientRequest.emit (events.js:211:7)
    at TLSSocket.socketErrorListener (_http_client.js:387:9)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:64:8)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
(node:1949) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1949) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.


  1 passing (55ms)

Тест проходит, однако я получаю это длинное неприятное предупреждение, что это значит и как мне от него избавиться?


РЕДАКТИРОВАТЬ

describe("testing endpoints for calculator Rest API", function () {

    before("starting the server..", function(done) {
        httpServer = app.listen(PORT, done)
        console.info(`server listening on port:${PORT}...`)
    })

     describe("testing the add endpoint", function(done){
         it("add endpoints result should evaluate to 10", function(){
            fetch(`${BASE_URL}add/5/5`).then(response => expect(response.result).to.be(10)).then(done).catch(done)
         })
     })

дает трассировку стека:

  ✓ add endpoints result should evaluate to 10
(node:27175) UnhandledPromiseRejectionWarning: FetchError: request to https://localhost:1234/api/calc/add/5/5 failed, reason: socket hang up
    at ClientRequest.<anonymous> (/home/jonas/Desktop/testdemo1/node_modules/node-fetch/lib/index.js:1444:11)
    at emitOne (events.js:116:13)
    at ClientRequest.emit (events.js:211:7)
    at TLSSocket.socketErrorListener (_http_client.js:387:9)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:64:8)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
(node:27175) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:27175) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

У меня точно такая же проблема...

Rouz 06.03.2019 01:11

@Rouz, если вы найдете решение, напишите как ответ :)

Jonas Grønbek 06.03.2019 08:57

Забавно, что для меня это не детерминировано. Он не работает при случайных вызовах. Иногда вообще не выходит из строя. Я пытаюсь создать интеграционный тест, так что это действительно убивает меня...

Rouz 06.03.2019 11:41

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

Rouz 06.03.2019 13:32

@Rouz, ха-ха, все в порядке. Хотя поздравляю с исправлением. Буду продолжать исправлять :)

Jonas Grønbek 06.03.2019 13:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
885
2

Ответы 2

Вы должны вызывать done() в своих тестах, в обратном вызове, когда тест завершен. Функция done передается обратному вызову, который вы используете в блоке it. Кроме того, вы всегда должны отлавливать свои ошибки https://mochajs.org/#асинхронный код

const expect = require("chai").expect
const PORT = require("../server").PORT
const app = require("../server").app
const fetch = require("node-fetch")

const BASE_URL = `https://localhost:${PORT}/api/calc/`
let httpServer;
describe("testing endpoints for calculator Rest API", function () {

    before("starting the server..", function(done) {
        httpServer = app.listen(PORT)
        console.info("server is started")
        done()
    })

     describe("testing the add endpoint", function(){
         console.info("testing the API now!")
         it("add endpoints result should evaluate to 10", function(done){
            fetch(`${BASE_URL}add/5/5`)
            .then(response => {
              expect(response.result).to.be(10)
              done();
            }).catch(e => done(e)) // or just .catch(done)
         })
     })
     after("shutting down the server..", function(){
        httpServer.close()  
     })

})

заканчивающийся на done() в функциях it, к сожалению, не решает предупреждение :(

Jonas Grønbek 06.03.2019 00:18

Вам нужно вызвать done после завершения асинхронной операции, в настоящее время вы вызываете done до того, как http-сервер сможет запуститься, и вы никогда не вызываете done при закрытии http-сервера. Вы можете просто передать done всем обработчикам асинхронных обратных вызовов.

before("starting the server..", function (done) {
    httpServer = app.listen(PORT, done) // <- here
})

describe("testing the add endpoint", function () {
    console.info("testing the API now!")
    it("add endpoints result should evaluate to 10", function (done) {
        fetch(`${BASE_URL}add/5/5`)
            .then(response => {
                expect(response.result).to.be(10)
            })
            .then(done) // <- here
            .catch(done) // <- here
    })
})
after("shutting down the server..", function (done) {
    httpServer.close(done) // <- here
})

Как вы можете видеть здесь, я НЕ присоединял оператор then к функции it.

fetch(`${BASE_URL}add/5/5`).then(response => expect(response.result).to.be(10)).then(done).catch(done)

Если это не решит вашу проблему, вероятно, проблема связана с маршрутом для /add/5/5.

Вы не можете вызвать .then в функции it?

Jonas Grønbek 06.03.2019 08:53

@JonasGrønbek then является частью цепочки обещаний fetch, она не привязана к it.

Jake Holzinger 06.03.2019 18:08

hotzinger it() не возвращает обещание, и я пробовал ваше решение, и оно работает, но, по-видимому, не устраняет предупреждение.

Jonas Grønbek 06.03.2019 18:25

Я думаю, у вас возникли проблемы с чтением кода, который я предоставил. Так что я сделаю это одним лайнером ...

Jake Holzinger 06.03.2019 23:11

Я пробовал это, и это не решает это, приятель. Я могу нажать на github, если вы готовы разгадать эту загадку. Прошу прощения, но это было не так.

Jonas Grønbek 06.03.2019 23:19

Вероятно, вам следует создать файл Минимальный, полный и проверяемый пример.

Jake Holzinger 06.03.2019 23:37

вы, вероятно, должны увидеть мою реальную кодовую базу, я понятия не имею, как еще упростить

Jonas Grønbek 06.03.2019 23:42

Другие вопросы по теме