我正在使用本地 Docker 镜像对 MongoDB 运行一些集成测试。我在 Jest 中有一些拆卸代码,以确保清理与 MongoDB 的所有连接:
import { client } from "../lib/common/mongodb";
module.exports = async function () {
await client.close();
};
这看起来很简单,但每次我打电话
client.close()
我都会收到以下错误:
/home/ian/src/my-proj/node_modules/mongodb/lib/sdam/topology.js:217
drainWaitQueue(this[kWaitQueue], new error_1.MongoTopologyClosedError());
^
MongoTopologyClosedError: Topology is closed
at /home/ian/src/my-proj/node_modules/mongodb/src/sdam/topology.ts:493:46 {
[Symbol(errorLabels)]: Set(0) {}
}
Node.js v20.2.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
在本例中,Mongo 客户端的单例实例中的
client
;
let client;
let clientPromise;
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
let globalWithMongo = global;
const uri = MONGO_SERVER_URL.replace("<username>", MONGO_USERNAME).replace("<password>", MONGO_PASSWORD);
if (!globalWithMongo._mongoClientPromise) {
client = new MongoClient(uri, options);
globalWithMongo._mongoClientPromise = client.connect();
}
clientPromise = globalWithMongo._mongoClientPromise;
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise;
export { client };
有谁知道为什么我可能会收到此错误以及如何调试它以确保我的测试干净退出?我必须添加以下 hack 来解决它(因为 client.close 不会抛出可捕获的异常)。
import { client } from "../lib/common/mongodb";
module.exports = async function () {
process.on('unhandledRejection', (e) => {
console.log("This is a hack, to deal with MongoDB not shutting down properly. It does not interfere with Jest test failures");
process.exit(0);
});
await client.close();
};
根据文档,该错误表明您正在尝试针对不可用的连接运行查询。
这可能是由于使用单个数据库连接造成的。
解决方案:
使用全局 Jest 拆卸和设置来打开和关闭数据库连接。
此代码在尝试关闭连接之前测试数据库当前是否已连接。
const { client } = require("../lib/common/mongodb");
beforeAll(async () => {
// Set up any necessary resources before running tests
await client.connect();
});
afterAll(async () => {
// Teardown and clean up resources after running tests
if (client.isConnected()) {
await client.close();
}
});