Я пытаюсь научиться тестировать с помощью 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, если вы найдете решение, напишите как ответ :)
Забавно, что для меня это не детерминировано. Он не работает при случайных вызовах. Иногда вообще не выходит из строя. Я пытаюсь создать интеграционный тест, так что это действительно убивает меня...
святой дым, мне удалось решить мою проблему, но это, безусловно, не та же проблема, что и у вас. Я даже не думаю, что стоит отвечать, поскольку проблема очень специфична для моей кодовой базы (сервер перезагружался в середине интеграционного теста). Извини друг
@Rouz, ха-ха, все в порядке. Хотя поздравляю с исправлением. Буду продолжать исправлять :)





Вы должны вызывать 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, к сожалению, не решает предупреждение :(
Вам нужно вызвать 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?
@JonasGrønbek then является частью цепочки обещаний fetch, она не привязана к it.
hotzinger it() не возвращает обещание, и я пробовал ваше решение, и оно работает, но, по-видимому, не устраняет предупреждение.
Я думаю, у вас возникли проблемы с чтением кода, который я предоставил. Так что я сделаю это одним лайнером ...
Я пробовал это, и это не решает это, приятель. Я могу нажать на github, если вы готовы разгадать эту загадку. Прошу прощения, но это было не так.
Вероятно, вам следует создать файл Минимальный, полный и проверяемый пример.
вы, вероятно, должны увидеть мою реальную кодовую базу, я понятия не имею, как еще упростить
У меня точно такая же проблема...