Typeorm Соединение "по умолчанию" не было найдено при создании соединения в jest globalSetup - PullRequest
1 голос
/ 19 июня 2020

У меня проблема, аналогичная # 5164 и в этом вопросе . Рассмотрим следующий рабочий тестовый код:

// AccountResolver.test.ts
describe('Account entity', () => {
  it('add account', async () => {
    await createConnections()
    const defaultConnection = getConnection('default')

    const actual = await callGraphql(
      `mutation {
        addAccount(options: {
          accountIdentifier: "7csdcd8-8a5f-49c3-ab9a-0198d42dd253"
          name: "Jake, Bob (Braine-l’Alleud) JAM"
          userName: "Bob.Marley@contoso.com"
        }) {
          accountIdentifier
          name
          userName
        }
      }`
    )
    expect(actual.data).toMatchObject({
      data: {
        addAccount: {
          accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
          name: 'Jake, Bob (Braine-l’Alleud) JAM',
          userName: 'Bob.Marley@contoso.com',
        },
      },
    })

    await defaultConnection.query(`DELETE FROM Account`)
    await defaultConnection.close()
  })
})

Код для создания соединения и его закрытия должен выполняться перед всеми тестами и после завершения всех тестов, поэтому мы добавили его в globalSetup.ts и globalTeardown.ts:

// globalSetup.ts
require('ts-node/register')
import { createConnections } from 'typeorm'

module.exports = async () => {
  // console.log('jest setup')
  await createConnections()
}
// globalTeardown.ts
require('ts-node/register')
import { getConnection } from 'typeorm'

module.exports = async () => {
  const defaultConnection = getConnection('default')
  await defaultConnection.close()
}
// AccountResolver.test.ts
describe('Account entity', () => {
  it('add account', async () => {
    const defaultConnection = getConnection('default')
    await defaultConnection.query(`DELETE FROM Account`)

    const actual = await callGraphql(
      `mutation {
        addAccount(options: {
          accountIdentifier: "7csdcd8-8a5f-49c3-ab9a-0198d42dd253"
          name: "Jake, Bob (Braine-l’Alleud) JAM"
          userName: "Bob.Marley@contoso.com"
        }) {
          accountIdentifier
          name
          userName
        }
      }`
    )
    expect(actual.data).toMatchObject({
      data: {
        addAccount: {
          accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
          name: 'Jake, Bob (Braine-l’Alleud) JAM',
          userName: 'Bob.Marley@contoso.com',
        },
      },
    })
  })
})

Пропуск строки require('ts-node/register') из обоих файлов вызывает эту ошибку:

T: \ Test \ src \ it- portal \ entity \ Account.ts: 1 import {^^^^^^ SyntaxError: Невозможно использовать оператор импорта вне модуля

Сохранение строки require в throws:

FAIL src / resolvers / AccountResolver.test.ts × добавить учетную запись (31 мс) ● Сущность учетной записи ›добавить учетную запись ConnectionNotFoundError: соединение« по умолчанию »не найдено. Сущность учетной записи

Версия

    "jest": "^26.0.1",
    "ts-jest": "^26.1.0",
    "ts-node-dev": "^1.0.0-pre.44",
    "typescript": "^3.9.5"

Конфиг

// jest.config.js
module.exports = {
  preset: 'ts-jest',
  globalSetup: './src/test-utils/config/globalSetup.ts',
  globalTeardown: './src/test-utils/config/globalTeardown.ts',
  setupFiles: ['./src/test-utils/config/setupFiles.ts'],
  moduleDirectories: ['node_modules', 'src'],
  globals: {
    'ts-jest': {
      tsConfig: 'tsconfig.json',
      diagnostics: {
        warnOnly: true,
      },
    },
  },
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
  coverageReporters: ['json', 'lcov', 'text', 'clover'],
}

Спасибо, что указали на мои ошибки. Поскольку я новичок, я пробовал поискать в Google, но не смог найти ответа, если это я не понимаю инструмент или ошибка в нем тоже. Обнаружена похожая проблема здесь с PR .

Кажется, что тесты выполняются в полностью изолированной среде, где они не могут получить доступ к подключению, установленному внутри globalSetup.

Обходной путь

Единственный обходной путь, который я нашел до сих пор, - это добавить следующий код в каждый тестовый файл:

beforeAll(async () => {
  await createConnections()
})

afterAll(async () => {
  const defaultConnection = getConnection('default')
  await defaultConnection.close()
})

1 Ответ

1 голос
/ 19 июня 2020

require('ts-node/register') не должно присутствовать в файлах .ts. Они уже обработаны компилятором TypeScript.

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

Это может быть достигнуто путем предоставления общей настройки в опции setupFilesAfterEnv:

// jest.setup.ts
...
beforeAll(async () => {
  await createConnections()
})

afterAll(async () => {
  const defaultConnection = getConnection('default')
  await defaultConnection.close()
})

Поскольку тесты Jest выполняются параллельно, это приведет к нескольким соединениям с базой данных. Если это нежелательно из-за ограничения количества подключений, необходимо использовать параметр Jest runInBand.

Настройка для всех тестов нежелательна, потому что не всем тестовым пакетам требуется подключение к базе данных, хотя они безусловно займут время и пул соединений с базой данных. В этом случае jest.setup.ts можно импортировать непосредственно в тесты, которые используют базу данных вместо setupFilesAfterEnv, без необходимости указывать beforeAll и afterAll в каждом наборе.

...