使用Jest与MongoMemoryReplSet时出现异步操作未退出报错
Fix Jest Not Exiting After Tests with MongoMemoryReplSet
我之前在使用MongoMemoryReplSet搭配Jest(26.x版本)时也遇到过完全一样的问题——测试跑完后Jest卡在那里不退出,提示有未关闭的异步操作。结合你给出的代码和依赖版本,这里有几个关键调整点可以解决这个问题:
1. 修复Mongoose连接的异步处理逻辑
你在beforeAll里混用了await和回调函数来处理Mongoose连接,这可能导致连接初始化的异步流程没有被正确等待,残留未处理的连接句柄。建议改成纯async/await的方式,去掉回调:
beforeAll(async () => { await replSet.waitUntilRunning(); const uri = await replSet.getUri(); try { // 直接await连接,不再使用回调 await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false }); await new User(testUser).save(); } catch (err) { console.error(err); process.exit(1); } });
2. 优化测试后的清理顺序和ReplSet停止逻辑
你的afterAll里的清理步骤有两个可以优化的地方:
- 用
mongoose.disconnect()代替mongoose.connection.close(),前者会断开Mongoose管理的所有连接,而后者只关闭默认连接,可能残留其他连接句柄。 - 给
replSet.stop()加上{ force: true }参数,强制MongoMemoryReplSet终止所有关联的MongoDB进程,避免残留后台进程导致句柄未释放。
修改后的afterAll:
afterAll(async () => { // 断开所有Mongoose连接 await mongoose.disconnect(); // 强制停止ReplSet,确保清理所有进程 await replSet.stop({ force: true }); });
3. 额外排查步骤(如果问题依然存在)
如果调整后还是无法退出,试试下面的方法:
- 运行测试时加上
jest --detectOpenHandles参数,Jest会输出具体的未关闭句柄信息,帮你定位残留的异步操作。 - 检查测试用例中是否有未清理的定时器(比如
setTimeout、setInterval)、未resolve/reject的Promise,或者其他第三方库的异步操作没有被正确终止。
这些调整应该能彻底清理所有相关的异步资源,让Jest在测试完成后正常退出。
内容的提问来源于stack exchange,提问作者Abishek Kumar
相关产品推荐
相关产品推荐

