Reputation: 379
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)
Upvotes: 4
Views: 1191
Reputation: 807
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
Upvotes: 5
Reputation: 191
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!
Upvotes: 3