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

使用Jest/mongodb-memory-server测试API出现setTimeout及连接报错

根因说明

你遇到的超时报错只是表象,核心错误是下面这个Mongoose连接冲突:

MongooseError: Can't call openUri() on an active connection with different connection strings.

触发原因是你测试API时,supertest启动的应用本身已经执行了一次Mongoose连接初始化(比如应用入口自带的数据库连接逻辑),同时测试文件的beforeAll钩子又调用了db.connect去连接mongodb-memory-server的实例,两次连接用了不同的URI导致冲突,后续的钩子逻辑卡壳才触发超时,单纯调高超时阈值无法解决问题。

解决方案

  • 第一步:隔离测试环境的应用连接逻辑
    在应用的数据库初始化代码处加环境判断,测试环境下不要让应用自行初始化数据库连接,统一使用测试用的db模块管理连接:
// 应用原有的数据库连接逻辑处添加判断
if (process.env.NODE_ENV !== 'test') {
  // 原有的mongoose.connect初始化代码
}
  • 第二步:优化测试db模块的连接逻辑
    修改Tests/db.js的connect方法,先判断当前是否有活跃连接,避免重复调用连接方法:
module.exports.connect = async () => {
  // readyState为0表示未连接,非0状态直接跳过连接逻辑
  if (mongoose.connection.readyState !== 0) {
    return
  }
  const uri = await mongod.getUri() // mongod为你初始化的MongoMemoryServer实例
  const mongooseOpts = {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  };
  await mongoose.connect(uri, mongooseOpts);
};
  • 第三步:补全数据库清理、关闭逻辑
    确保clearDatabase只清理集合数据不关闭连接,closeDatabase要同时断开Mongoose连接和停止mongodb-memory-server实例:
// 清理数据逻辑
module.exports.clearDatabase = async () => {
  const collections = mongoose.connection.collections
  for (const key in collections) {
    await collections[key].deleteMany({})
  }
}

// 关闭连接逻辑
module.exports.closeDatabase = async () => {
  await mongoose.connection.dropDatabase()
  await mongoose.connection.close()
  await mongod.stop() // 停止内存数据库实例
}
  • 第四步(可选):处理多测试文件并行冲突
    如果存在多个测试文件都用到内存数据库,可在jest.config.js中添加配置让测试串行执行,避免多实例连接冲突:
// jest.config.js
module.exports = {
  // 其他配置
  maxWorkers: 1
}

如果测试跑完后仍提示Jest未正常退出,可在启动命令中添加--forceExit参数强制退出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:15:08