简而言之::当我尝试在Node.js中关闭MongoDB连接时,MonogDB驱动程序似乎已按预期关闭了连接本身,但是后台中的某些东西似乎在等待套接字直到它关闭(大约)超时,这会阻止像Jest这样的事情彻底结束。
魔鬼:
我正在使用NPM软件包"mongodb": "^3.1.11"
(Node.js MongoDB Driver 3.1)和"jest": "^23.6.0"
,并且我知道您应该在测试完成后关闭连接。
MongoDB example by Jest当前似乎与Node.js MongoDB Driver 2.x相关,并且版本3不再具有db.close()
方法。
这是我的简单测试文件:
// example.test.js
const { MongoClient } = require('mongodb');
let client;
let db;
beforeAll(async () => {
client = await MongoClient.connect('mongodb://localhost:27017', {
useNewUrlParser: true,
});
db = await client.db('testdb');
});
afterAll(async () => {
await client.close(); // Returns successfully
});
it('should insert and find document', async () => {
const collection = db.collection('files');
await collection.insert({name: 'Jest'});
const doc = await collection.findOne({name: 'Jest'});
expect(doc._id).toBeDefined();
expect(doc.name).toBe('Jest');
});
测试完成后,MongoDB连接显然已成功关闭。我什至可以通过检查MongoDB服务器日志(end connection 127.0.0.1:33312 (0 connections now open)
)来确认这一点,但Jest仍然拒绝结束该过程。推荐的Jest CLI选项--detectOpenHandles
不输出任何内容。
我意识到6分钟后Jest最终会成功结束; 6分钟=== 360000毫秒,恰好是socketTimeoutMS
options中MongoClient.connect
的默认值。
如果我为socketTimeoutMS
设置了自定义值,则Jest将在指定时间后完成。从上方编辑测试文件:
// ...
beforeAll(async () => {
client = await MongoClient.connect('mongodb://localhost:27017', {
useNewUrlParser: true,
socketTimeoutMS: 1000, // <----- insert this line
});
db = await client.db('testdb');
});
// ...
现在,Jest将在仅延迟1秒而不是6分钟后完成。
我不知道套接字超时在这里真正做什么,以及为什么MongoDB驱动程序在关闭连接后等待套接字超时。可能是驱动程序中的错误,也可能是我做错了。
我还发现,使用force
方法(close
)的client.close(true)
选项似乎可以在本地(MacOS)解决此问题,但不幸的是,在CI服务器上(Linux) / Docker)。 Jest CLI选项--forceExit
也是如此。
有什么想法可以干净地关闭MongoDB连接吗?