【问题标题】:NodeJs using pg client - Jest has detected the following open handle potentially keeping Jest from exiting - TCPWRAPNodeJs 使用 pg 客户端 - Jest 检测到以下打开的句柄可能阻止 Jest 退出 - TCPWRAP
【发布时间】:2021-06-13 08:05:13
【问题描述】:

在我的 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 添加到我的npm test 脚​​本时,我得到以下信息:

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 测试仍然不会退出(同样的错误)。

如果我使用 pg Client 并执行此操作,我会遇到与 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());
   })
  })
});

【问题讨论】:

  • 对于初学者来说,您无需等待请求结束。在最里面的回调中调用done,或者最好使用promise。
  • 感谢@Estus Flask。我尝试使用done,但没有成功。请在 OP 中查看我的“更新”。有什么想法吗?
  • 此时从 Jest 的角度来看是可以的。见stackoverflow.com/questions/34803691/…。 pg-promise 可能是推荐的方法,因为 Node 多年来一直支持 Promise。
  • 另外,您对done 的使用无效。不是.then(done()),而是.then(done)。有很大的不同。

标签: node.js postgresql jestjs


【解决方案1】:

我不确定我是否正确,但您的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()
}

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

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

【讨论】:

    猜你喜欢
    • 2020-09-20
    • 2021-09-26
    • 2019-03-13
    • 2020-08-24
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 2018-11-14
    相关资源
    最近更新 更多