Jest测试中MongoDB单连接持久化配置问题求助
如何在Jest中配置MongoDB单持久连接避免多连接问题
问题分析
你遇到的核心问题是Jest默认并行运行测试文件,每个文件会启动独立的工作进程,导致每个进程都会执行数据库连接代码,进而创建多个MongoDB连接。之前尝试的几种方法失效原因如下:
- 全局设置文件:Jest的
globalSetup/globalTeardown在独立进程中运行,无法将连接共享给测试进程,执行完毕后连接会被销毁。 - beforeAll/afterAll:每个测试文件的
beforeAll钩子会在各自的工作进程中触发,mongoose.connection.readyState检查仅对当前进程有效,无法跨进程复用连接。 - setupFilesAfterEnv:同样因并行进程的隔离性,每个进程都会执行连接逻辑,导致多连接。
解决方案
方案一:串行运行测试(简单直接)
通过让Jest串行执行所有测试文件,确保整个测试流程仅创建一个数据库连接。
修改jest.config.js,添加runInBand配置:
module.exports = { testEnvironment: 'node', setupFilesAfterEnv: ['./tests/db_config.js'], verbose: true, preset: '@shelf/jest-mongodb', testTimeout: 30000, runInBand: true // 启用串行测试 };
你的db.config.js无需修改,因为串行模式下仅会执行一次beforeAll:
beforeAll(() => { if (mongoose.connection.readyState >= 1) { return; } mongoose.set('strictQuery', false); mongoose.connect(process.env.MONGO_URI_TEST, { useNewUrlParser: true, useUnifiedTopology: true, }); mongoose.connection.on('error', (err) => { throw err; }); }); afterAll(async () => { await mongoose.disconnect(); });
优缺点:实现简单,但测试执行速度会因串行而变慢,适合小型测试套件。
方案二:模块级单例连接(兼顾速度与连接数控制)
利用Node.js模块缓存机制,创建一个单例连接模块,确保每个工作进程仅创建一次连接,连接数等于Jest工作进程数(默认等于CPU核心数)。
- 创建单例连接模块
tests/mongo-singleton.js:
const mongoose = require('mongoose'); let isConnected = false; async function connect() { if (isConnected) { console.log('复用现有MongoDB连接'); return; } try { await mongoose.connect(process.env.MONGO_URI_TEST, { useNewUrlParser: true, useUnifiedTopology: true, }); isConnected = true; console.log('MongoDB连接成功'); } catch (err) { console.error('MongoDB连接失败:', err); throw err; } } async function disconnect() { if (isConnected) { await mongoose.disconnect(); isConnected = false; console.log('MongoDB连接已断开'); } } module.exports = { connect, disconnect };
- 修改
tests/db_config.js,调用单例连接:
const { connect } = require('./mongo-singleton'); beforeAll(async () => { await connect(); }); afterAll(async () => { const { disconnect } = require('./mongo-singleton'); await disconnect(); });
- 调整
jest.config.js(无需串行配置):
module.exports = { testEnvironment: 'node', setupFilesAfterEnv: ['./tests/db_config.js'], verbose: true, preset: '@shelf/jest-mongodb', testTimeout: 30000 };
优缺点:测试仍可并行执行,速度不受影响;每个工作进程仅创建一个连接,避免了大量冗余连接,适合大型测试套件。
内容的提问来源于stack exchange,提问作者Abdelouahab Bella
相关产品推荐
相关产品推荐

