Jest тесты зависают из-за открытых соединений Sequelize - PullRequest
1 голос
/ 14 февраля 2020

Настройка

У меня есть NodeJS проект , который использует:

Sequelize создается при загрузке модуля моделей, который импортируется несколькими файлами, которые тестируются с помощью Jest.

Проблема

Тесты Jest проходят, но затем зависают с сообщением:

Jest не завершается через одну секунду после завершения тестового прогона.

Обычно это означает, что существуют асинхронные операции, которые не были остановлены в ваших тестах. Чтобы устранить эту проблему, попробуйте запустить Jest с --detectOpenHandles.

Примечание: Добавление --detectOpenHandles к тестовому вызову не влияет на вывод.

На самом деле я не вызываю объект sequelize из каких-либо тестовых путей, однако некоторые из протестированных файлов импортируют модуль models и, следовательно, создается экземпляр Sequelize.

(я также отмечу, что это происходит только в моей среде TravisCI, но я подозреваю, что это красная сельдь.)

Context

Поскольку Jest выполняет тесты параллельно, модуль models загружается несколько раз в течение весь процесс тестирования. Я подтвердил это выводом отладки, в котором было указано SEQUELIZE LOADED, которое появляется несколько раз при запуске тестов.

Попытки

  1. Я пытался вызвать sequelize.close() внутри a globalTeardown но это, кажется, просто открывает (а затем закрывает) новое соединение с секвенированием.

  2. Поскольку ни один из тестов фактически не использует соединение с базой данных, Я попытался запустить sequelize.close() в модуле models непосредственно перед экспортом. Это устранило проблему (хотя, очевидно, это не является решением).

  3. Я попытался настроить пулы тестовых соединений для агрессивного завершения соединений.

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

Это ничего не сделало.

Требования

  1. Я не хочу использовать решение грубой силы, такое как запуск --forceExit через Jest при запуске мои тесты. Такое ощущение, что он игнорирует проблему root и может подвергнуть меня другим видам ошибок в будущем.

  2. Мои тесты распределены по десяткам файлов, что означает необходимость вызова что-то в afterAllTests потребовало бы большой избыточности и привнесло бы запах кода.

Вопрос

Как я могу гарантировать, что соединения завершаются после завершающих тестов sh, чтобы они не приводили к зависанию Jest?

1 Ответ

4 голосов
/ 17 февраля 2020

Jest предоставляет способ создавать универсальные настройки перед каждым набором тестов . Это означает, что Jest's afterAll можно использовать для закрытия пула соединений секвелирования без необходимости вручную включать его в каждый отдельный набор тестов.

Пример конфигурации Jest в 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.

Это означает, что будут закрыты соединения, которые, возможно, никогда не были открыты (что является немного грубой силы) но это может быть лучшим вариантом.

...