mongodb-memory-server 8与Jest集成运行失败如何解决
最新版mongodb-memory-server(v9.x)+ Jest + Express 集成配置方案
当前最新版本mongodb-memory-server和旧版API存在不兼容变更,官方指南缺失全局环境隔离、实例复用相关的必要配置,可按以下步骤完成配置:
1. 安装依赖
执行以下命令安装测试所需依赖:
npm install -D jest mongodb-memory-server mongoose supertest
2. 编写全局测试生命周期文件
在项目根目录新建test目录,在目录下创建4个全局配置文件,实现内存Mongo实例全局复用,避免每个测试文件重复启动实例:
global-setup.js:测试启动前初始化内存Mongo实例
const { MongoMemoryServer } = require('mongodb-memory-server'); module.exports = async () => { // 固定Mongo二进制版本,和生产环境大版本保持一致,避免重复下载 const mongod = await MongoMemoryServer.create({ binary: { version: '7.0.5' } }); // 将连接URI注入全局环境变量 process.env.MONGO_TEST_URI = mongod.getUri(); // 挂载实例到全局,供后续关闭逻辑调用 global.__MONGOD_INSTANCE__ = mongod; };
global-teardown.js:所有测试执行完成后销毁内存实例
module.exports = async () => { if (global.__MONGOD_INSTANCE__) { await global.__MONGOD_INSTANCE__.stop(); } };
custom-test-env.js:自定义Jest测试环境,解决Jest多工作线程下环境变量隔离导致拿不到Mongo连接串的问题
const NodeEnvironment = require('jest-environment-node').default; class MongoTestEnvironment extends NodeEnvironment { async setup() { await super.setup(); this.process.env.MONGO_TEST_URI = process.env.MONGO_TEST_URI; } } module.exports = MongoTestEnvironment;
setup-after-each.js:每个测试用例执行完成后清理数据,避免用例间脏数据干扰
const mongoose = require('mongoose'); afterEach(async () => { if (mongoose.connection.readyState !== 0) { const collections = mongoose.connection.collections; for (const collName in collections) { await collections[collName].deleteMany({}); } } }); afterAll(async () => { await mongoose.disconnect(); });
3. 修改Jest配置
在根目录jest.config.js中补充以下配置项,关联刚才编写的全局文件:
module.exports = { testEnvironment: '<rootDir>/test/custom-test-env.js', globalSetup: '<rootDir>/test/global-setup.js', globalTeardown: '<rootDir>/test/global-teardown.js', setupFilesAfterEach: ['<rootDir>/test/setup-after-each.js'], testMatch: ['**/*.test.js', '**/*.spec.js'] };
4. 测试用例写法示例
测试文件中不需要重复启动内存Mongo实例,直接连接全局注入的URI即可:
const request = require('supertest'); const mongoose = require('mongoose'); const app = require('../src/app'); // 导入项目的Express实例 beforeAll(async () => { await mongoose.connect(process.env.MONGO_TEST_URI); }); describe('接口测试示例', () => { it('GET / 应返回200状态码', async () => { const res = await request(app).get('/'); expect(res.statusCode).toBe(200); }); });
常见问题处理
- 旧教程中使用的
getConnectionString()方法已在新版正式废弃,统一使用getUri()获取连接串 - 不要在单个测试文件中重复调用
MongoMemoryServer.create(),会导致多实例占用端口、内存占用过高 - 若遇到Mongo二进制下载失败问题,可配置
MONGOMS_DOWNLOAD_MIRROR环境变量指向可用的国内镜像源 - 若使用TypeScript,只需将上述配置文件改为TS格式,在jest配置中补充ts-node相关注册逻辑即可
内容的提问来源于stack exchange,提问作者JimmyTheCode
相关产品推荐
相关产品推荐

