【发布时间】: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