Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple connections with same name are created in e2e test of NestJs with in memory database

I have NestJs application with TypeORM configured with mysql. I want to have e2e(integration) test and for that reason I want to have in memory database in the tests which I configured this way:

{
    type: 'sqlite',
    database: ':memory:',
    synchronize: true,
    dropSchema: true,
    entities: [`dist/**/*.entity{.ts,.js}`],
}

And the setup of the tests

beforeEach(async () => {
        const moduleFixture: TestingModule =
            await Test.createTestingModule({imports: [AppModule, UserModule]})
                .overrideProvider(TypeOrmConfigService).useClass(MockTypeOrmConfigService)
                .compile();

        app = await moduleFixture.createNestApplication();
        await app.init();
    });

. When running the test I got

AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.
    at new AlreadyHasActiveConnectionError (/Users/user/workspace/app/src/error/AlreadyHasActiveConnectionError.ts:8:9)
    at ConnectionManager.Object.<anonymous>.ConnectionManager.create (/Users/user/workspace/app/src/connection/ConnectionManager.ts:57:23)
    at Object.<anonymous> (/Users/user/workspace/app/src/index.ts:228:35)
    at step (/Users/user/workspace/app/node_modules/tslib/tslib.js:136:27)
    at Object.next (/Users/user/workspace/app/node_modules/tslib/tslib.js:117:57)
    at /Users/user/workspace/app/node_modules/tslib/tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/Users/user/workspace/app/node_modules/tslib/tslib.js:106:16)
    at Object.createConnection (/Users/user/workspace/app/node_modules/typeorm/index.js:186:20)
    at rxjs_1.defer (/Users/user/workspace/app/node_modules/@nestjs/typeorm/dist/typeorm-core.module.js:151:29)
(node:19140) UnhandledPromiseRejectionWarning: AlreadyHasActiveConnectionError: Caught error after test environment was torn down

If I move the setup from beforeEach in beforeAll block it's ok, but I'm afraid that when I create several specs the error will come back. How should be handled properly?

EDIT: The problem was that each test is making a setup of the application and so creates a new connection.The solution was to use "keepConnectionAlive: true," in order all tests to reuse same connection.

like image 786
Christopher Panalov Avatar asked Oct 03 '19 13:10

Christopher Panalov


3 Answers

keepCOnnectionAlive: true is the way to go

like image 82
0xCAP Avatar answered Nov 19 '22 10:11

0xCAP


Base on 0xCAP's answer, you can do something like this also.

// jest.setup.ts
jest.mock("/path/to/database/config/object", () => {
    const { databaseConfig, ...rest } = jest.requireActual("/path/to/database/config/object")

    return {
        ...rest,
        databaseConfig: {
            ...databaseConfig,
            keepConnectionAlive: true // replace old config
        }
    }
})
// jest.config.js
module.exports = {
  ...other options
  setupFilesAfterEnv: ["jest.setup.ts"],
}
like image 32
Gompro Avatar answered Nov 19 '22 08:11

Gompro


Using keepConnectionAlive: true produced the following error for me.

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.

Adding the below to each e2e test fixed my issue:

afterEach(async () => {
    await app.close();
});
like image 2
Louis Avatar answered Nov 19 '22 08:11

Louis