使用 pg 客户端的 NodeJs - Jest 检测到以下打开句柄可能会阻止 Jest 退出 - TCPWRAP

Chr*_*row 11 postgresql node.js jestjs

在 Node.js 中的一些集成测试中,我会pg在测试运行后对 Postgres 测试数据库执行一些清理操作。我将其称为afterAll()

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

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

\n
Jest did not exit one second after the test run has completed.\n\nThis usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
Jest has detected the following 1 open handle potentially keeping Jest from exiting:\n\n  \xe2\x97\x8f  TCPWRAP\n\n> 259 |   pool.query('TRUNCATE someTable RESTART IDENTITY CASCADE;', (err, res) => {\n      |        ^\n  260 |       \n  261 |       pool.end();\n  262 |   })\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

如果我使用 pgClient并执行此操作,我会遇到类似的问题client.connect()

\n
  client.connect()\n  client\n    .query('TRUNCATE someTable RESTART IDENTITY CASCADE;')\n    .then(() => client.end())\n
Run Code Online (Sandbox Code Playgroud)\n

谁能解释一下这里到底发生了什么?Jest 是否在最终测试后尝试关闭,但 中的操作afterAll()阻止了这种情况?我需要做什么才能让测试退出?其他类似问题中的解决方案均不适用于我的案例。

\n

更新

\n

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

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

Yoe*_*nov 0

我不确定我是否正确,但这似乎不是您pool.end所期待的,也不是通过await或通过老式的承诺。尝试这个-

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()
}
Run Code Online (Sandbox Code Playgroud)

此外,如下所述,postgres 的连接数量有限,因此关闭连接始终是一个好习惯,尤其是在测试时。

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