首页 > 解决方案 > MongoError: pool is draining, 在集成测试中使用 MongoMemoryServer 时禁止新操作

问题描述

我正在使用MongoMemoryServer编写集成测试。我有两个集成测试文件。当我运行 IT 测试时,我看到以下内容。我不明白为什么。我正在使用 jestjs 测试框架。

当我有两个 IT 测试文件时,我看到以下错误

MongoError: pool is draining, new operations prohibited

      37 |   for (const key in collections) {
      38 |     const collection = collections[key];
    > 39 |     await collection.deleteMany();
         |                      ^
      40 |   }
      41 | };

这是我的设置

//db-handler.js
const mongoose = require("mongoose");
const { MongoMemoryServer } = require("mongodb-memory-server");
const mongod = new MongoMemoryServer();

module.exports.connect = async () => {
  const uri = await mongod.getConnectionString();

  const mongooseOpts = {
    useNewUrlParser: true,
    autoReconnect: true,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000,
  };

  await mongoose.connect(uri, mongooseOpts);
};

module.exports.closeDatabase = async () => {
  await mongoose.connection.dropDatabase();
  await mongoose.connection.close();
  await mongod.stop();
};

module.exports.clearDatabase = async () => {
  const collections = mongoose.connection.collections;

  for (const key in collections) {
    const collection = collections[key];
    await collection.deleteMany();
  }
};

我所有的 IT 测试设置都是这样的

//example.it.test.js
const supertest = require("supertest");
const dbHandler = require("./db-handler");
const app = require("../../src/app");
const request = supertest(app);

const SomeModel = require("../Some");
beforeAll(async () => await dbHandler.connect());
afterEach(async () => await dbHandler.clearDatabase());
afterAll(async () => await dbHandler.closeDatabase());

describe("Some Test Block", () => {
  it("Test One", async (done) => {
    await SomeModel.create({a: "a", b "b"});

    const response = await request.get("/endPointToTest");
    expect(response.status).toBe(200);

    done();
  });

当我只有一个 IT 测试文件时,一切正常。当我引入一个类似于设置的新 IT 测试文件时example.it.test.js,新测试失败。上面的示例错误消息。

我错过了什么?当我有多个 IT 测试文件时,我的设置是否需要更改?

更新一:我的 package.json 文件看起来像

{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest --runInBand ./tests"
  },
  "devDependencies": {
    "jest": "^25.2.7",
    "mongodb-memory-server": "^6.5.2",
    "nodemon": "^2.0.2",
    "supertest": "^4.0.2"
  },
  "jest": {
    "testEnvironment": "node",
    "coveragePathIgnorePatterns": [
      "/node_modules/"
    ]
  }
}

标签: node.jsmongodbmongoosejestjsintegration-testing

解决方案


默认情况下,Jest 与“运行测试的子进程的工作池”(Jest CLI 文档)并行运行测试。根据 Jest 文档。

每个测试文件都与导致错误的 mogodb 服务器建立新连接。

您可以运行Jest测试 sequentially 来避免此问题。

Jest CLI 的 --runInBand 或 -i 选项允许您按顺序运行测试(在非并行模式下)。

如果您使用 node js 或 mongoose 的官方 mongodb 库,则可能会出现此错误(池正在耗尽,禁止新操作)。请在建立 mongodb 连接时指定池大小。

module.exports.connect = async () => {
  const uri = await mongod.getConnectionString();
  const mongooseOpts = {
    useNewUrlParser: true,
    autoReconnect: true,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000,
    poolSize: 10,
  };
  await mongoose.connect(uri, mongooseOpts);
};


推荐阅读