인프런 커뮤니티 질문&답변

jeongho218님의 프로필 이미지
jeongho218

작성한 질문수

탄탄한 백엔드 NestJS, 기초부터 심화까지

TDD 소개 및 통합 테스팅

AlreadyHasActiveConnectionError 에러 발생

해결된 질문

작성

·

260

·

수정됨

0

에러 해결하였습니다..

app.module.ts > typeOrmModuleOptions에

keepConnectionAlive: true 옵션이 빠져있어 발생한 에러였습니다.

 

검색해보니 '어플리케이션 종료 시 DB 연결 유지'에 대한 내용인데

제가 다른 옵션과 착각하고 주석 처리했었습니다.

 

현재 옵션 활성화 하였고 e2e 테스트 정상적으로 진행되는거 확인했습니다.

const typeOrmModuleOptions = {
  useFactory: async (
    configService: ConfigService,
  ): Promise<TypeOrmModuleOptions> => ({
    namingStrategy: new SnakeNamingStrategy(),
    // ...
    keepConnectionAlive: true,
  }),

 

검색해보니 beforeEach에 있는 app.init() 메소드에서 어플리케이션을 초기화하며 DB 연결도 초기화되는데,

어플리케이션을 재초기화하는 것이지 종료한 적은 없었기에 여전히 'default'라는 이름으로 활성화된 DB 연결이 존재하였고,

DB 연결 재초기화 중 'default라는 이름으로 새로운 DB 연결이 실패하였다' 에러가 발생한 것이며

 

keepConnectionAlive: true 옵션을 줌으로써

DB 연결은 어플리케이션의 생명주기와는 별도로 존재하게 되고, 이미 활성화된 DB 연결이 존재하므로 새로운 DB 연결을 시도하지 않는다 라고 합니다..

공부가 되었네요.

 

app.e2e-spec.ts의 afterEach 메소드는 제거하였습니다.

 

 

=============================================================

 

 

안녕하세요 강사님

강의따라 진행하다 에러가 발생하여 질문글 남깁니다.

 

에러 메세지는 아래와 같습니다.

[Nest] 26544  - 2023. 11. 25. 오후 11:01:36   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.
    at AlreadyHasActiveConnectionError.TypeORMError [as constructor] (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\error\TypeORMError.ts:7:9)
    at new AlreadyHasActiveConnectionError (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\error\AlreadyHasActiveConnectionError.ts:8:9)
    at ConnectionManager.Object.<anonymous>.ConnectionManager.create (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\connection\ConnectionManager.ts:57:23)
    at C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\globals.ts:77:35
    at step (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:143:27)
    at Object.next (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:124:57)
    at C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:117:75
    at new Promise (<anonymous>)
    at Object.__awaiter (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:113:16)
    at createConnection (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\typeorm\globals.js:55:20)
[Nest] 26544  - 2023. 11. 25. 오후 11:01:39   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)...
AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.
    at AlreadyHasActiveConnectionError.TypeORMError [as constructor] (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\error\TypeORMError.ts:7:9)
    at new AlreadyHasActiveConnectionError (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\error\AlreadyHasActiveConnectionError.ts:8:9)
    at ConnectionManager.Object.<anonymous>.ConnectionManager.create (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\connection\ConnectionManager.ts:57:23)
    at C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\src\globals.ts:77:35
    at step (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:143:27)
    at Object.next (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:124:57)
    at C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:117:75
    at new Promise (<anonymous>)
    at Object.__awaiter (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\tslib\tslib.js:113:16)
    at createConnection (C:\Users\admin\OneDrive\바탕 화면\typeorm-in-the-nest\node_modules\typeorm\globals.js:55:20)
 FAIL  test/app.e2e-spec.ts (10.952 s)
  AppController (e2e)
    √ / (GET) (845 ms)
    hello jest
      × two plus two is four (5014 ms)

  ● AppController (e2e) › hello jest › two plus two is four

    thrown: "Exceeded timeout of 5000 ms for a hook.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

       7 |   let app: INestApplication;
       8 |
    >  9 |   beforeEach(async () => {
         |   ^
      10 |     const moduleFixture: TestingModule = await Test.createTestingModule({        
      11 |       imports: [AppModule],
      12 |     }).compile();

      at app.e2e-spec.ts:9:3
      at Object.<anonymous> (app.e2e-spec.ts:6:1)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        11.106 s
Ran all test suites.
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 

 

읽어보니 이미 'default'라는 이름의 연결이 존재하고, 현재 활성화 중이므로 같은 이름의 연결을 또 생성할 수 없다는 것 같고,

검색해보니 beforeEach 메소드 안에 Test.createTestingModule이 매 테스트마다 DB 연결을 시도하는 상황이라고 나왔습니다..

 

하여 아래와 같이 afterEach 메소드를 사용하여 매 테스트마다 어플리케이션을 종료해주도록 코드를 수정하였습니다.

describe('AppController (e2e)', () => {
  let app: INestApplication;

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

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

  // 테스트 2개 이상 사용할 경우 필요한 메소드
  afterEach(async () => {
    await app.close();
  });

  it('/ (GET)', () => {
    return request(app.getHttpServer())
      .get('/')
      .expect(200)
      .expect('typeorm in nest, just coding');
  });

  describe('hello jest', () => {
    it('two plus two is four', () => {
      expect(2 + 2).toBe(4);
    });
  });

// 생략

 

수정 후 강의에서 진행했던 내용은 모두 완료가 되었는데..

이제 궁금한 점은

강사님과 코드 내용이 같고 도커나 DB 연결에 대하여 특별히 수정한 내용이 없는데

왜 이런 상황이 발생하는 것인지. 버전이 달라 발생한 상황인 것인지..

 

그리고 afterEach를 사용하였을때 당장 테스트 진행은 가능하지만 이대로 사용해도 괜찮을지 안좋은 것은 아닌지가 궁금합니다..

답변

답변을 기다리고 있는 질문이에요
첫번째 답변을 남겨보세요!
jeongho218님의 프로필 이미지
jeongho218

작성한 질문수

질문하기