Jest测试由于开放的Sequelize连接而挂起

时间:2020-02-13 22:27:01

标签: node.js postgresql jestjs sequelize.js travis-ci

设置

我有一个NodeJS project,它使用:

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

问题

Jest测试通过,但随后挂起消息:

测试运行一秒钟后,Jest没有退出。

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

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

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

(我还将注意到,这仅发生在我的TravisCI环境中,但我怀疑这是一条红鲱鱼。)

上下文

由于Jest并行运行测试,因此models模块在​​整个测试过程中被多次加载。我用调试输出SEQUELIZE LOADED证实了这一点,该调试输出在我运行测试时会多次出现。

尝试

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

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

  3. 我已尝试将测试连接池配置为积极终止连接。

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

这什么也没做。

要求

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

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

问题

如何确保测试完成后关闭sequelize连接,以免引起Jest挂起?

1 个答案:

答案 0 :(得分:11)

玩笑提供了一种前往create universal setup before every test suite的方式。这意味着可以利用Jest的afterAll来关闭序列化连接池,而不必在每个测试套件中手动添加它。

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

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