You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mongoose时NestJS(Jest)测试无法终止问题求助

Jest测试通过但无法终止:Mongoose多数据库连接关闭问题

问题场景

使用Mongoose连接多个MongoDB数据库,Jest测试全部通过,但测试进程始终无法自动终止。相关代码如下:

连接定义(mongoDB.service.ts)

private connections: Map<number, Connection> = new Map();
private connection: Connection;

多数据库连接方式

this.connection.useDb(dbName);

实现的OnApplicationShutdown接口

async onApplicationShutdown(): Promise<void> {
    for (const [orgId, connection] of this.connections) {
      await connection
        .close()
        .then(() => {
          console.log(`Connection for organization ID ${orgId} closed.`);
        })
        .catch((e) => {
          console.error(`Failed to close connection for organization ID ${orgId}: ${e}`);
        });
    }
    this.connections.clear();
    await this.connection
      .close()
      .then(() => {
        console.log("Secondary MongoDB connection closed.");
      })
      .catch((e) => {
        console.error(`Failed to close secondary MongoDB connection: ${e}`);
      });
    await mongoose.connection
      .close()
      .then(() => {
        console.log("Primary MongoDB connection closed.");
      })
      .catch((e) => {
        console.error(`Failed to close primary MongoDB connection: ${e}`);
      });
  }

测试中的afterAll钩子

afterAll(async () => {
    await module.close();
}, 60000);

调试显示所有连接已关闭,但测试进程仍无法终止。

解决方法

1. 确保useDb返回的连接被正确追踪

useDb会返回新的连接实例,而非修改原连接。如果你的代码仅调用this.connection.useDb(dbName)却未将返回实例存入connections,会导致部分连接遗漏关闭。修正代码:

// 替换原useDb调用逻辑
const orgConnection = this.connection.useDb(dbName);
this.connections.set(orgId, orgConnection);

2. 关闭连接时添加{ force: true }参数

Mongoose的close()默认等待所有异步操作完成,测试场景下可强制关闭,避免残留操作阻塞进程:

// 遍历关闭子连接
await connection.close({ force: true });

// 关闭主连接
await this.connection.close({ force: true });
await mongoose.connection.close({ force: true });

3. 在afterAll中手动终止事件循环

若确认所有资源已清理但进程仍未退出,可强制终止Node.js事件循环:

afterAll(async () => {
    await module.close();
    process.exit(0);
}, 60000);

注意:仅在确认无资源泄漏时使用,避免掩盖潜在问题。

4. 排查残留的异步句柄

使用Node.js调试参数定位未处理的Promise、定时器等:

jest --trace-warnings

根据输出清理残留的异步操作。

内容的提问来源于stack exchange,提问作者Dean Taler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:22:40