The TypeORM connection named "default" could not be located during the creation of the connection in a Jest globalSetup environment

I've encountered a similar issue as the one discussed in #5164 and also in this thread. Here is a sample of working test code:

// 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: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7c3e131e52311d0e1019053c1f131208130f13521f1311">[email protected]</a>"
        }) {
          accountIdentifier
          name
          userName
        }
      }`
    )
    expect(actual.data).toMatchObject({
      data: {
        addAccount: {
          accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
          name: 'Jake, Bob (Braine-l’Alleud) JAM',
          userName: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f5b79a97dbb8948799908cb5969a9b819a869adb969a98">[email protected]</a>',
        },
      },
    })

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

The code snippet for establishing a connection and closing it should be executed before and after all tests, which is why it has been included in globalSetup.ts and globalTeardown.ts:

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

module.exports = async () => {
  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: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="20624f420e6d41524c455960434f4e544f532e454a4b">[email protected]</a>"
        }) {
          accountIdentifier
          name
          userName
        }
      }`
    )
    expect(actual.data).toMatchObject({
      data: {
        addAccount: {
          accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
          name: 'Jake, Bob (Braine-l’Alleud) JAM',
          userName: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="41032e236f0c20332d243801222e2f352e32650c232c2d">[email protected]</a>',
        },
      },
    })
  })
})

If the line require('ts-node/register') is omitted from both files, it results in the following error:

T:\Test\src\it-portal\entity\Account.ts:1 import { ^^^^^^ SyntaxError: Cannot use import statement outside a module

However, including the require line throws:

FAIL src/resolvers/AccountResolver.test.ts × add account (31 ms) ● Account entity › add account ConnectionNotFoundError: Connection "default" was not found.Account entity

Version

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

Config

// 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'],
}

Thank you for highlighting my errors. I tried searching for a solution as a newbie, but couldn't determine whether it's my lack of understanding or a tool bug. Came across a similar issue here with a relevant PR.

It seems like the tests run in a completely isolated environment where they cannot access the connection set up in globalSetup.

Workaround

The only workaround I've discovered so far is to include the following code in each test file:

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

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

Answer №1

It is unnecessary to include 'require('ts-node/register')' in .ts files as they are already processed by TypeScript compiler.</p>

<p><code>globalSetup
and globalTeardown serve different purposes. They execute in the Jest parent process and are only evaluated once, whereas each test suite runs in child processes.

To achieve this functionality, a common setup can be provided in the setupFilesAfterEnv option:

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

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

Due to Jest running tests in parallel, multiple database connections may be created. To address connection limit concerns, utilize the Jest runInBand option.

Setting up a common setup for all tests may not be ideal as not all test suites require a database connection. This could unnecessarily consume time and occupy the database connection pool. Instead, jest.setup.ts can be directly imported into tests requiring a database connection, eliminating the need to specify beforeAll and afterAll in each suite.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Join the nested Observables array

I have an array that holds objects, each containing two properties where one is an observable value. let myArray = [{def: 'name1', value: EventEmitter_}, {def: 'name2', value: EventEmitter_}] My goal is to subscribe to the observables ...

Despite having both React and Firebase enabled, the "sign-in provider" feature appears to be disabled

Within my Authentication settings, the Sign-in Method is configured to use Email and Password as enabled. I've set up a handler for form submission that looks like this: createUser(e){ e.preventDefault(); const email = this.createEmail.value ...

The initial processing step for the export namespace is to utilize the `@babel/plugin-proposal-export-namespace-from` plugin. Previous attempts to resolve this issue have been

I encountered a problem with my application and found two related questions on the same topic. However, due to a lack of reputation, I am unable to comment or ask questions there. That's why I'm reaching out here... Recently, I integrated Redux ...

Exploring the concept of nested views in AngularJS's UI Router with multiple views integration

I am facing an issue with configuring multiple views on one page, where one view is nested within another. My code in app.js does not seem to be working properly. Below are the details: This is my index.html file <body ng-app="configuratorApp" > ...

Ways to decrease font size and insert a line break within a constrained input space?

I am facing an issue where the input box remains static with old numbers when it overflows, and newly typed numbers do not appear at all. <!DOCTYPE html> <html> <body> <input type="text" id="output-area" placehold ...

Tips for isolating all the Javascript loaded via ajax or jquery.load within a specific child scope instead of a global scope

I am currently working on a solution to embed a third-party page into my site using ajax/jquery.load() to avoid using iframes (CORS requirements are already handled by the third party). My dilemma lies in the fact that the main host site loads jquery 1.x ...

Tips for launching a fresh window and embedding HTML into it with jQuery?

I'm attempting to use JavaScript to open a new window, but the HTML content is not being added: var callScriptText = $('#callScriptText').html(); var url = '/Action/CallScript/?callScript='; // Open the current call script in a n ...

What steps can be taken to turn off specific warning rules for CSS mode in ACE editor?

Utilizing the Ace Editor (through Brace and React-Ace) is a key aspect of my project. In our implementation, we specify the editor's mode as "css" and integrate it into our webpage. While this setup functions correctly, we have observed that some of ...

Error: AngularJS form validation is not working properly

I've been following the AngularJS documentation, but I'm having trouble with my validations. The error messages are not showing up and the minimum length restrictions for the form fields are not working: <form name="callbackForm" ng-submit="r ...

typescript, generate a new type by merging option values

In typescript I am faced with a challenge. I have a type called A: interface A { a1: string; a2: int; } As well as another type called B: interface B { b1: number } Now, my goal is to create a new type: interface AB { a1?: string; a2? ...

Pressing the Enter key does not initiate a redirect on the page

Hey there! I've set up a text field where users need to input a password in order to download a PDF file. If the password is correct, they are directed to the URL of the PDF file. However, if the password is wrong, they are redirected to a page called ...

Having trouble with your jQuery code not loading properly?

Currently working on debugging jQuery code and facing an issue where a particular section of the code is not being triggered upon clicking. The HTML/PHP in question: $cartlink .= "<a class='add_to_cart button' data-id='{$product->id} ...

Issue with the iOS gyroscope detected when rotating specifically around the z-axis

I am facing a unique challenge with an unusual bug and I'm looking for help from anyone who has encountered this issue before or can provide a solution. My current project involves using Javascript to access the gyro on iOS devices, specifically focu ...

Transferring checkbox data to Bootstrap modals and dynamically summoning specific div modals using their unique identifiers

I have been trying to populate the checkbox values into corresponding modal divs based on button clicks, but I am facing difficulties in achieving it. Desired outcome: The buttons should trigger the display of selected checkbox values in their respective ...

Sorting items in backbone.js can be achieved by using the sortBy method

Currently, I am delving into learning backbone.js and have decided to create my own Todo application using backbone.js along with a local storage plugin. At this point, I have successfully developed the Todo app where you can add and remove tasks. However, ...

Just a straightforward Minimum Working Example, encountering a TypeScript error TS2322 that states the object is not compatible with the type 'IntrinsicAttributes & Props & { children?: ReactNode; }'

Currently, I am immersed in a project involving React and Typescript. I am grappling with error code TS2322 and attempting to resolve it. Error: Type '{ submissionsArray: SubmissionProps[]; }' is not assignable to type 'IntrinsicAttributes ...

Error Occurred: ngRepeat directive encountered an invalid expression while attempting to render the

HTML <tr ng-repeat="sale as examples"> <td class="text-right"> @{{sale.sales_person}}</td> <td class="text-right"> @{{sale.sales_total}}</td> <td class="text-right"> @{{sale.sales_target_amount}}</td> ...

Is there a way to eliminate duplicate elements from 2 arrays in Angular?

Imagine I have a scenario with two arrays: arr1 = ["Tom","Harry","Patrick"] arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"] Is it possible to eliminate the duplicate elements in these arrays? The desired output would be: arr2 = ["Miguel"," ...

The async waterfall is encountering a Typeerror due to the nextcallback function not being defined properly

async.waterfall([1,2,3,4].map(function (arrayItem) { return function (lastItemResult, nextCallback) { // performing the same operation for each item in the array var itemResult = (arrayItem+lastItemResult); // pa ...

What is the process of displaying events from components within ng2 submodules?

My dilemma involves two components with straightforward output events and handlers. I am attempting to pass a value from a child submodule to a component within my app.module. Here is the snippet of code from my app.component.ts: @Component({ selector: ...