Jest 测试由于打开的 Sequelize 连接而挂起
Jest tests hang due to open Sequelize connections
设置
我有一个 NodeJS project 使用:
Sequelize 是在加载模型模块时实例化的,该模块由一些正在使用 Jest 测试的文件导入。
问题
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.
注意:在测试调用中添加--detectOpenHandles
不影响输出。
我实际上并没有从任何测试路径调用 sequelize
对象,但是一些测试文件导入了 models
模块,因此实例化了 Sequelize。
(我还会注意到这只发生在我的 TravisCI 环境中,但我怀疑这是一个转移注意力的问题。)
背景
因为 Jest 是 运行 并行测试,所以 models
模块在整个测试过程中被加载了多次。我用调试输出证实了这一点 SEQUELIZE LOADED
当我 运行 测试时出现多次
尝试
我确实尝试在 globalTeardown
中调用 sequelize.close()
但这似乎只是打开(然后关闭)一个新的续集连接。
由于 none 的测试实际上依赖于数据库连接,因此我在导出前立即尝试在 models
模块中 运行ning sequelize.close()
.这解决了问题(虽然显然不是解决方案)。
我已尝试将测试连接池配置为主动终止连接。
const sequelizeConfig = {
...
pool: {
idle: 0,
evict: 0,
}
}
这没有任何作用。
要求
我不想在 运行 我的测试时通过 Jest 使用暴力解决方案,例如 运行ning --forceExit
。这感觉就像它忽略了根本问题,可能会让我面临其他类型的错误。
我的测试分布在数十个文件中,这意味着需要在 afterAllTests
中调用某些内容将需要大量冗余并且会引入代码味道。
问题
如何确保在测试完成后关闭 sequelize 连接,以免它们导致 Jest 挂起?
Jest 提供了一种 create universal setup before every test suite. This means it is possible to leverage Jest's afterAll 关闭 sequelize 连接池的方法,而无需手动将其包含在每个测试套件中。
package.json
中的 Jest 配置示例
"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
。
这确实意味着将关闭可能永远不会打开的连接(这有点蛮力)但这可能是最好的选择。
设置
我有一个 NodeJS project 使用:
Sequelize 是在加载模型模块时实例化的,该模块由一些正在使用 Jest 测试的文件导入。
问题
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.
注意:在测试调用中添加--detectOpenHandles
不影响输出。
我实际上并没有从任何测试路径调用 sequelize
对象,但是一些测试文件导入了 models
模块,因此实例化了 Sequelize。
(我还会注意到这只发生在我的 TravisCI 环境中,但我怀疑这是一个转移注意力的问题。)
背景
因为 Jest 是 运行 并行测试,所以 models
模块在整个测试过程中被加载了多次。我用调试输出证实了这一点 SEQUELIZE LOADED
当我 运行 测试时出现多次
尝试
我确实尝试在
globalTeardown
中调用sequelize.close()
但这似乎只是打开(然后关闭)一个新的续集连接。由于 none 的测试实际上依赖于数据库连接,因此我在导出前立即尝试在
models
模块中 运行ningsequelize.close()
.这解决了问题(虽然显然不是解决方案)。我已尝试将测试连接池配置为主动终止连接。
const sequelizeConfig = {
...
pool: {
idle: 0,
evict: 0,
}
}
这没有任何作用。
要求
我不想在 运行 我的测试时通过 Jest 使用暴力解决方案,例如 运行ning
--forceExit
。这感觉就像它忽略了根本问题,可能会让我面临其他类型的错误。我的测试分布在数十个文件中,这意味着需要在
afterAllTests
中调用某些内容将需要大量冗余并且会引入代码味道。
问题
如何确保在测试完成后关闭 sequelize 连接,以免它们导致 Jest 挂起?
Jest 提供了一种 create universal setup before every test suite. This means it is possible to leverage Jest's afterAll 关闭 sequelize 连接池的方法,而无需手动将其包含在每个测试套件中。
package.json
中的 Jest 配置示例
"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
。
这确实意味着将关闭可能永远不会打开的连接(这有点蛮力)但这可能是最好的选择。