So I'm using jest
to test my node.js application and the tests finish fine but I'm getting a message from jest about open handles. Any insights?
jest --detectOpenHandles
PASS src/libs/user/tests/user_model_test.js PASS src/tests/app_test.js PASS src/libs/user/tests/user_service_test.js
Test Suites: 3 passed, 3 total Tests: 14 passed, 14 total Snapshots: 0 total Time: 7.209s Ran all test suites.
Jest has detected the following 4 open handles potentially keeping Jest from exiting:
● PROMISE
2 | // we use a test database for testing 3 | var mongoDB = 'mongodb://localhost/my_db_conn'; > 4 | mongoose.connect(mongoDB); | ^ 5 | const User = require('../user_model'); 6 | 7 | describe("User model test", () => { at NativeConnection.Object.<anonymous>.Connection.openUri (node_modules/mongoose/lib/connection.js:424:19) at Mongoose.Object.<anonymous>.Mongoose.connect (node_modules/mongoose/lib/index.js:208:15) at Object.<anonymous> (src/libs/user/__tests__/user_model_test.js:4:10)
● PROMISE
8 | }); 9 | > 10 | module.exports = mongoose.model("User", UserSchema); | ^ at Function.init (node_modules/mongoose/lib/model.js:962:16) at Mongoose.Object.<anonymous>.Mongoose.model (node_modules/mongoose/lib/index.js:392:11) at Object.<anonymous> (src/libs/user/user_model.js:10:27) at Object.<anonymous> (src/libs/user/__tests__/user_model_test.js:5:14)
● PROMISE
8 | }); 9 | > 10 | module.exports = mongoose.model("User", UserSchema); | ^ at Function.init (node_modules/mongoose/lib/model.js:962:16) at Mongoose.Object.<anonymous>.Mongoose.model (node_modules/mongoose/lib/index.js:392:11) at Object.<anonymous> (src/libs/user/user_model.js:10:27) at Object.<anonymous> (src/libs/user/index.js:1:41)
● PROMISE
3 | var mongoose = require('mongoose'); 4 | var mongoDB = 'mongodb://localhost/my_db_conn'; > 5 | mongoose.connect(mongoDB); | ^ 6 | 7 | describe('App test', () => { 8 | it('has a module', () => { at NativeConnection.Object.<anonymous>.Connection.openUri (node_modules/mongoose/lib/connection.js:424:19) at Mongoose.Object.<anonymous>.Mongoose.connect (node_modules/mongoose/lib/index.js:208:15) at Object.<anonymous> (src/__tests__/app_test.js:5:10)
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: please also note @SimonSimCity 's comment, this solution comes with some tradeoffs. Consider using Özgür Atmaca's answer by disconnecting the mongoose connection instead.
It seems your mongoose connection remains open after your test, try one of the following:
close server instance after test.
const server = require('./app'); //server instance
server.close(); //put in afterAll or afterEach depending on your test
close your database connection after all your test.
afterAll(()=>{ mongoose.connection.close();});
wrap your mongoose connection with async/await.
async function(){
await mongoose.connect(mongoDB);
};
try one or a combination. These are my solutions since I can't really see your code.
It's related to model.init
function which returns promise. Quick fix will be to pass skipInit
flag while creating the model like this:
const User = mongoose.model("users", userSchema, "users", true)
skipInit
is the fourth parameter in this function
But in this case it will not initialize indexes for your model, so it's better to set this flag according to the process.env.NODE_ENV
const skipInit = process.env.NODE_ENV === "test"
const User = mongoose.model("users", userSchema, "users", skipInit)
I was having same issue with Mongoose and managed to fix it like this 👇
beforeAll(async () => {
await mongoose.disconnect();
await mongoose.connect(MONGODB_URL, MONGODB_OPTIONS);
});
Most "solutions" I found was around timers and I am not a fan of fixing things with timers, so above workaround feels more natural to me, hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With