设置
我有一个 NodeJS 项目,它使用:
- 开玩笑进行测试。
- 续集为ORM。
Sequelize 在加载模型模块时实例化,该模块由一些正在使用 Jest 测试的文件导入。
问题所在
开玩笑测试通过,但随后挂起消息:
Jest 在测试运行完成后一秒钟没有退出。
这通常意味着存在不是异步操作 在您的测试中停止。考虑使用
--detectOpenHandles
解决此问题。
注意:
向测试调用添加--detectOpenHandles
不会影响输出。
我实际上并没有从任何测试路径调用sequelize
对象,但是一些测试文件导入了models
模块,因此实例化了 Sequelize。
(我还要注意的是,这只发生在我的 TravisCI 环境中,但我怀疑这是一个红鲱鱼。
背景
由于 Jest 并行运行测试,因此在整个测试过程中多次加载models
模块。 我通过调试输出确认了这一点,该输出显示SEQUELIZE LOADED
在我运行测试时多次出现。
尝试
-
我确实尝试在
globalTeardown
内调用sequelize.close()
,但这似乎只是打开(然后关闭(一个新的续集连接。 -
由于没有任何测试实际上依赖于数据库连接,因此我尝试在导出前立即在
models
模块中运行sequelize.close()
。 这解决了问题(尽管显然不是解决方案(。 -
我已尝试将测试连接池配置为主动结束连接。
const sequelizeConfig = {
...
pool: {
idle: 0,
evict: 0,
}
}
这什么也没做。
要求
我不想使用暴力解决方案,例如在运行测试时通过 Jest 运行
--forceExit
。这感觉就像它忽略了根本问题,可能会让我面临其他类型的错误。我的测试分布在数十个文件中,这意味着需要在
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
.
这确实意味着连接将被关闭,可能永远不会打开(这有点蛮力(,但这可能是最好的选择。