使用pg client-Jest的NodeJ检测到以下打开句柄可能会阻止Jest退出-TCPWRAP



在Node.js中的一些集成测试中,我使用pg在测试运行后对Postgres测试数据库进行一些清理。我在afterAll():中称之为

afterAll(() => {
const { Pool } = require('pg')
const connectionString = 'postgresql://' + PG_USER + ':' + PASSWORD + '@' + HOST + ':' + PG_PORT + '/' + DATABASE_TEST;
const pool = new Pool({
connectionString,
})
pool.query('TRUNCATE someTable RESTART IDENTITY CASCADE;', (err, res) => {
pool.end();
})

当我在Node.js应用程序中运行Jest测试时,我得到了错误:

Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

当我在package.json中将--detectOpenHandles添加到我的npmtest脚本中时,我得到以下内容:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:
●  TCPWRAP
> 259 |   pool.query('TRUNCATE someTable RESTART IDENTITY CASCADE;', (err, res) => {
|        ^
260 |       
261 |       pool.end();
262 |   })

如果我将到数据库的连接移动到一个单独的文件中(在__tests__文件夹之外(,Jest测试仍然不会退出(出现相同的错误(。

如果我使用pgClient并这样做,那么client.connect()也会出现类似的问题

client.connect()
client
.query('TRUNCATE someTable RESTART IDENTITY CASCADE;')
.then(() => client.end())

有人能解释一下这里到底发生了什么吗?Jest是否试图在最终测试后关闭,但afterAll()中的操作阻止了这一点?我需要做什么才能允许测试退出?其他类似SO问题中的解决方案都不适用于我的案例。

更新

我尝试了@Estus Flask的建议,但它仍然不能解决问题。使用以下(它将done作为回调函数传递,这样afterAll在调用done()之前不会完成(当pool.end()承诺解析时,我调用它(:

afterAll( done => {
const { Pool } = require('pg')
const connectionString = 'postgresql://' + PG_USER + ':' + PASSWORD + '@' + HOST + ':' + PG_PORT + '/' + DATABASE_TEST;
const pool = new Pool({
connectionString,
})
pool.query('TRUNCATE someTable RESTART IDENTITY CASCADE;', (err, res) => {
pool.end().then(done());
})
})
});

我不确定我是否正确,但似乎没有等待您的pool.end,也没有通过await或旧的fasion承诺。试试这个-

afterAll(async () => {
const { Pool } = require('pg')
const connectionString = 'postgresql://' + PG_USER + ':' + PASSWORD + '@' + HOST + ':' + PG_PORT + '/' + DATABASE_TEST;
const pool = new Pool({
connectionString,
})

await pool.query('TRUNCATE someTable RESTART IDENTITY CASCADE;')
await pool.end()
}

此外,如下所述,postgres的连接数量有限,因此,关闭连接总是一种很好的做法,尤其是在测试中。

默认情况下,Compose上的所有PostgreSQL部署都以连接限制开始,该连接限制将允许的最大连接数设置为100。

在这里的其他答案的基础上,对池和池客户端进行微观管理对我来说很有效:

describe('My Tests', () => {
let pool: Pool = null;
let client: PoolClient = null;
beforeAll(async () => {
pool = new Pool(connectionInfo);
client = await pool.connect();
.
.
.
}, 10000);
afterAll(async () => {
client.release();
await pool.end();
}, 10000);
.
.
.
};

最新更新