由于未关闭的Sequelize连接,Jest测试挂起

10

设置

我有一个使用NodeJS的项目,使用以下内容:

在加载模型模块时实例化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模块。我通过debug输出验证了这一点,当我运行测试时,出现了多个SEQUELIZE LOADED

尝试

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

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

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

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

这没有任何作用。

要求

  1. 我不想使用蛮力解决方案,例如通过Jest运行--forceExit来运行我的测试。这感觉像是忽略了根本问题,并可能在以后暴露给其他种类的错误。

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

问题

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

1个回答

22

Jest提供了一种方法在每个测试套件之前创建通用设置。这意味着可以利用Jest的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参数。

这意味着可能会关闭从未打开过的连接(有点粗暴),但这可能是最好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接