3

How to get rid of the openHandles left by mongoose.connect in jest test

const { startTestDB } = require("../conn");
const mongoose = require("mongoose");
const request = require("supertest");
const faker = require("faker");
const app = require("../app");
const fs = require("fs");

describe("test1: ", () => {
  beforeAll(() => {
    startTestDB()
      .then(() => {
        console.log("Connected to db.");
      })
      .catch((e) => {
        console.log(e);
      });
  });

  afterAll(() => {
    mongoose
      .disconnect()
      .then(() => {
        console.log('db connection is closed');
      })
      .catch((e) => {
        console.error(e);
      });
  });

  it("Should save a new user", async () =>
    request(app)
      .post("/save")
      .send({
        name: faker.internet.userName(),
        email: faker.internet.email()
      })
      .expect(201));
});

This is an example code that has the same problem, when I run npx jest --detectOpenHandles I find one at mongoose.connect, as per my knowledge open handles occur because of async operations that didn't finish before tests, but I clearly close the connection in afterAll.

The Error Message I got:

  ●  TLSWRAP

       9 |
      10 | module.exports.startTestDB = () =>
    > 11 |   mongoose.connect(
         |            ^
      12 |     `mongodb+srv://${mongodb.user}:${mongodb.password}@${mongodb.host}/${mongodb.db}-test?retryWrites=true&w=majority`,
      13 |     {
      14 |       useNewUrlParser: true,

      at parseSrvConnectionString (node_modules/mongodb/lib/core/uri_parser.js:67:7)
      at parseConnectionString (node_modules/mongodb/lib/core/uri_parser.js:597:12)
      at connect (node_modules/mongodb/lib/operations/connect.js:282:3)
      at node_modules/mongodb/lib/mongo_client.js:260:5
      at maybePromise (node_modules/mongodb/lib/utils.js:692:3)
      at MongoClient.Object.<anonymous>.MongoClient.connect (node_modules/mongodb/lib/mongo_client.js:256:10)
      at node_modules/mongoose/lib/connection.js:835:12
      at NativeConnection.Object.<anonymous>.Connection.openUri (node_modules/mongoose/lib/connection.js:832:19)
      at node_modules/mongoose/lib/index.js:351:10
      at node_modules/mongoose/lib/helpers/promiseOrCallback.js:32:5
      at promiseOrCallback (node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:10)
      at Mongoose.Object.<anonymous>.Mongoose._promiseOrCallback (node_modules/mongoose/lib/index.js:1149:10)
      at Mongoose.connect (node_modules/mongoose/lib/index.js:350:20)
      at startTestDB (conn.js:11:12)
      at tests/s.test.js:10:5
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
      at runJest (node_modules/@jest/core/build/runJest.js:387:19)
      at _run10000 (node_modules/@jest/core/build/cli/index.js:408:7)
      at runCLI (node_modules/@jest/core/build/cli/index.js:261:3)
  • did you find a solution? i have tried closing the connection like you and also did some changes to code as recommended in other answers but handles are still open for me – Fiehra Feb 16 '22 at 11:30
  • That may depend on a range of factors. I use `mongoose.connect()` in `beforeAll()` and `mongoose.disconnect()` in `afterAll()` and that does the trick at the moment in my case. I don't see open handles reported by Jest. – Manfred Oct 22 '22 at 10:37

2 Answers2

4

I am reposting my answer from this question jest and mongoose - jest has detected opened handles as this was my solution for the problem.

closing the connection as many others have proposed did not work for me.

after many hours of searching for a solution on SO and github issues, I came across this github thread https://github.com/visionmedia/supertest/issues/520 with multiple solutions offered. what was finally working for me was implementing a global-teardown-file in my root directory like so:

// test-teardown-globals.js
module.exports = () => {
  process.exit(0);
};

and also by adjusting my jest.config.js slightly

// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  globalTeardown: '<rootDir>/test-teardown-globals.js',
};

UPDATE: although this works this solution is only viable for developing and running tests locally. I also prefer Özgür Atmaca's solution by disconnecting before reconnecting in the beforeAll block

Fiehra
  • 659
  • 6
  • 23
3

I am too reposting my answer here: https://stackoverflow.com/a/73673449/4012944

Mongoose web site clearly does not recommend using Jest with Mongoose apps and does not recommend timers or global setups/teardowns.

Such workaround feels more natural to me.

beforeAll(async () => {
  await mongoose.disconnect();
  await mongoose.connect(MONGODB_URL, MONGODB_OPTIONS);
});

Hope it helps!

Liger
  • 140
  • 2
  • 4
  • I just added `await mongoose.disconnect()` in `afterAll()` and that did the trick for me. I don't see open handles reported by Jest. – Manfred Oct 22 '22 at 10:35