MongoError:池正在耗尽,在集成测试中使用 MongoMemoryServer 时禁止新操作

2024-04-26

我在用着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/"
    ]
  }
}

我认为在某些情况下错误消息可能会产生一定的误导。

问题似乎与“池大小太小”或“jest 并行运行测试”有关,因此池最终耗尽了可用池。

然而,如果你看看 mongo 销毁池时会发生什么,你就会明白了。

/**
 * Destroy pool
 * @method
 */
Pool.prototype.destroy = function(force, callback) {
  ...

  // Set state to draining
  stateTransition(this, DRAINING);

  ...

如果您尝试关闭连接,池会将其内部状态更改为“正在耗尽”,从而导致问题。

所以错误消息告诉我们的是,之后仍有未完成的写入操作正在进行pool.destroy.

就我而言,这是一个活动事件侦听器回调每 x 秒运行一次,它会写入 mongo。

我更改了测试代码以直接调用事件回调函数,而不是每 x 秒调用一次。

这解决了我的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoError:池正在耗尽,在集成测试中使用 MongoMemoryServer 时禁止新操作 的相关文章

随机推荐