Search code examples
jestjsapolloapollo-server

Kill or close websocket on apollo-server after jest test


I would like to know how can I close the websocket after the jest test ?

Currently I have this :

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
}

I launch this command :

npm run test

The test are executed, but on the watch, if I modify one test, I have this error :

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
}

After the test are executed, I look the port 4000, with this command : lsof -i:4000, and I see always :

enter image description here

The port isn't close...


Solution

  • server.listen returns a Promise that resolves to a ServerInfo object

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

    So you need to call global.httpServer.server.close().