【问题标题】:Mocha node HTTP testing - socket hang upMocha节点HTTP测试——socket挂断
【发布时间】:2019-07-27 12:35:27
【问题描述】:

我正在尝试学习使用节点进行测试,因为我正在使用 Mocha 框架。

我正在尝试向 express 服务器发出 get 请求,执行两个数字的计算并将其作为 {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.log("server is started")
        done()
    })

     describe("testing the add endpoint", function(){
         console.log("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.log(`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 哈哈,没关系。恭喜修复。我会继续修复:)

标签: node.js sockets promise mocha.js


【解决方案1】:

您必须在测试中调用done(),在测试完成后的回调中。 done 函数被传递给您在 it 块中使用的回调。此外,您应该确保始终发现您的错误https://mochajs.org/#asynchronous-code

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.log("server is started")
        done()
    })

     describe("testing the add endpoint", function(){
         console.log("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()  
     })

})

【讨论】:

  • 在 it 函数中以 done() 结尾很遗憾 - 没有解决警告:(
【解决方案2】:

您需要在异步操作完成后调用done,目前您在http 服务器有机会启动之前调用done,并且在关闭http 服务器时您永远不会调用done。您可以简单地将done 传递给所有异步回调处理程序。

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

describe("testing the add endpoint", function () {
    console.log("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 的路由可能存在问题。

【讨论】:

  • 你不能在it函数上调用.then?
  • @JonasGrønbek thenfetch 承诺链的一部分,它不附加到 it
  • hotzinger it() 没有返回承诺,我已经尝试了您的解决方案,它运行但显然没有解决警告。
  • 我认为您在阅读我提供的代码时遇到了问题。所以我会把它做成一个班轮......
  • 我试过了,还是不能解决。如果你想解开这个谜团,我可以推送到 github。很抱歉,事实并非如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2022-07-23
  • 2020-05-29
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多