开玩笑测试后杀死或关闭阿波罗服务器上的 websocket

Posted

技术标签:

【中文标题】开玩笑测试后杀死或关闭阿波罗服务器上的 websocket【英文标题】:Kill or close websocket on apollo-server after jest test 【发布时间】:2020-10-08 17:33:25 【问题描述】:

我想知道在玩笑测试后如何关闭 websocket?

目前我有这个:

packages.json

"scripts": 
    "test": "jest --watchAll"
  ,
  "jest": 
    "globalSetup": "./tests/jest/globalSetup.js",
    "globalTeardown": "./tests/jest/globalTeardown.js"
  ,

server.js

...
const server = new ApolloServer(
    typeDefs,
    resolvers,
    context(request) 
        return 
            prisma,
            request,
        
    ,
)

export  server as default 

globalSetup.js

require("@babel/register")

const server = require("../../server").default

// console.log(server)
module.exports = async () => 
    global.httpServer = await server.listen( port: 4000 )

globalTeardown.js

module.exports = async () => 
    console.log("stop") // Show stop in the console
    await global.httpServer.stop

我启动这个命令:

npm 运行测试

测试已执行,但在手表上,如果我修改一个测试,我有这个错误:

Error: listen EADDRINUSE: address already in use :::4000
    at Server.setupListenHandle [as _listen2] (net.js:1313:16)
    at listenInCluster (net.js:1361:12)
    at Server.listen (net.js:1449:7)
    at /Users/jeremiechazelle/Sites/project/server/node_modules/apollo-server/src/index.ts:128:18
    at new Promise (<anonymous>)
    at ApolloServer.<anonymous> (/Users/jeremiechazelle/Sites/project/server/node_modules/apollo-server/src/index.ts:123:11)
    at Generator.next (<anonymous>)
    at /Users/jeremiechazelle/Sites/project/server/node_modules/apollo-server/dist/index.js:18:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/jeremiechazelle/Sites/project/server/node_modules/apollo-server/dist/index.js:14:12)
Emitted 'error' event on WebSocketServer instance at:
    at Server.emit (events.js:316:20)
    at emitErrorNT (net.js:1340:8)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) 
  code: 'EADDRINUSE',
  errno: -48,
  syscall: 'listen',
  address: '::',
  port: 4000

测试执行后,我查看端口 4000,使用以下命令:lsof -i:4000,我总是看到:

端口没有关闭...

【问题讨论】:

【参考方案1】:

server.listen 返回一个解析为 ServerInfo 对象的 Promise

export interface ServerInfo 
  address: string;
  family: string;
  url: string;
  subscriptionsUrl: string;
  port: number | string;
  subscriptionsPath: string;
  server: http.Server;

所以你需要打电话给global.httpServer.server.close()

【讨论】:

感谢@Daniel 的回答,但是当我写 await global.httpServer.stop() 时,我看到一个错误:TypeError: global.httpServer.stop is not a function。从这个问题:github.com/apollographql/apollo-server/issues/3964 您需要使用require("../../server").default 显示您要导入的模块。例如,如果您要导出的是一个 express 实例,它没有stop 方法,但有一个close 方法。 我更新了我的帖子,我导入了一个 ApolloServer 实例。我尝试使用 close(),但我有同样的问题:TypeError: global.httpServer.close is not a function 谢谢@Daniel!

以上是关于开玩笑测试后杀死或关闭阿波罗服务器上的 websocket的主要内容,如果未能解决你的问题,请参考以下文章

在所有测试运行后开玩笑清理

测试成功完成后开玩笑没有终止

开玩笑单元测试返回“MongoError:拓扑被破坏”

server.close 不是函数

createWriteStream 的 ('error') 上的开玩笑单元测试

用玩笑测试打字稿中的私有函数