【问题标题】:Jest tests hang due to open Sequelize connections由于打开 Sequelize 连接,Jest 测试挂起
【发布时间】:2020-05-29 17:27:15
【问题描述】:

设置

我有一个 NodeJS project 使用:

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

问题

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

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

这通常意味着存在未执行的异步操作 在您的测试中停止。考虑运行 Jest --detectOpenHandles 解决此问题。

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

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

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

背景

因为 Jest 是并行运行测试,所以在整个测试过程中会多次加载 models 模块。我通过调试输出确认了这一点,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 挂起?

【问题讨论】:

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


    【解决方案1】:

    Jest 提供了一种create universal setup before every test suite 的方法。这意味着可以利用 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

    这确实意味着将关闭可能从未打开过的连接(这有点蛮力),但这可能是最好的选择。

    【讨论】:

      猜你喜欢
      • 2014-08-06
      • 2016-07-12
      • 1970-01-01
      • 2019-12-21
      • 2021-12-22
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多