开玩笑测试由于打开续集连接而挂起



设置

我有一个 NodeJS 项目,它使用:

  • 开玩笑进行测试。
  • 续集为ORM。

Sequelize 在加载模型模块时实例化,该模块由一些正在使用 Jest 测试的文件导入。

问题所在

开玩笑测试通过,但随后挂起消息:

Jest 在测试运行完成后一秒钟没有退出。

这通常意味着存在不是异步操作 在您的测试中停止。考虑使用--detectOpenHandles解决此问题。

注意: 向测试调用添加--detectOpenHandles不会影响输出。

我实际上并没有从任何测试路径调用sequelize对象,但是一些测试文件导入了models模块,因此实例化了 Sequelize。

(我还要注意的是,这只发生在我的 TravisCI 环境中,但我怀疑这是一个红鲱鱼。

背景

由于 Jest 并行运行测试,因此在整个测试过程中多次加载models模块。 我通过调试输出确认了这一点,该输出显示SEQUELIZE LOADED在我运行测试时多次出现。

尝试

  1. 我确实尝试在globalTeardown内调用sequelize.close(),但这似乎只是打开(然后关闭(一个新的续集连接。

  2. 由于没有任何测试实际上依赖于数据库连接,因此我尝试在导出前立即在models模块中运行sequelize.close()。 这解决了问题(尽管显然不是解决方案(。

  3. 我已尝试将测试连接池配置为主动结束连接。

const sequelizeConfig = {
...
pool: {
idle: 0,
evict: 0,
}
}

这什么也没做。

要求

  1. 我不想使用暴力解决方案,例如在运行测试时通过 Jest 运行--forceExit。这感觉就像它忽略了根本问题,可能会让我面临其他类型的错误。

  2. 我的测试分布在数十个文件中,这意味着需要在afterAllTests中调用某些内容将需要大量冗余,并且会引入代码异味。

问题

如何确保续集连接在测试完成后关闭,这样它们就不会导致 Jest 挂起?

Jest 提供了一种在每个测试套件之前创建通用设置的方法。 这意味着可以利用Jest的afterAll来关闭续集连接池,而无需手动将其包含在每个测试套件中。

package.json中的开玩笑配置示例

"jest": {
...
"setupFilesAfterEnv": ["./src/test/suiteSetup.js"]
}

示例suiteSetup.js

import models from '../server/models'
afterAll(() => models.sequelize.close())
// Note: in my case sequelize is exposed as an attribute of my models module.

由于setupFilesAfterEnv在每个测试套件之前加载,这确保了打开连接的每个Jest线程最终都关闭了该连接。

这不违反 DRY,也不依赖于笨拙的--forceExit.

这确实意味着连接将被关闭,可能永远不会打开(这有点蛮力(,但这可能是最好的选择。

最新更新