Nest.js에서 e2e test - test용 db 연결 & 매 실행마다 데이터 truncate
병원 데이터 추가 POST API가 우리 어플리케이션에 존재하지 않아서 test db에 병원 데이터를 미리 집어넣어줘야하는 과정이 필요함
Nest.js에서 e2e test를 위해 테스트용 DB를 연결하는 과정에서 시간이 좀 걸렸다.
import { smth } from './commons/something'
으로 상대 경로로 import되지 않고 import { smth } from 'src/commons/something'
이런식으로 절대 경로로 import되었었는데, e2e test를 돌려보니 여기서 에러가 떴었다. 그래서 모든 절대경로를 상대경로로 변경해주었다.import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';
import { INestApplication } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getConnection } from 'typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
describe('E2E 테스트', () => {
let app: INestApplication;
const configService: ConfigService;
beforeAll(async () => {
// 테스트 데이터베이스 연결 설정
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot(ConfigValidator),
AppModule, // 실제 애플리케이션 모듈
TypeOrmModule.forRoot({
// 테스트 데이터베이스 연결 정보
type: 'mysql',
host: configService.get("DB_HOST"),
port: configService.get("DB_PORT"),
username: configService.get("DB_USERNAME"),
password: configService.get("DB_PASSWORD"),
database: configService.get("TEST_DB"),
synchronize: true,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
}),
],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
// 테스트 케이스 작성
});
=> 이렇게 test db로 직접 연결을 해줬는데 계속 development db로 데이터가 추가되었다.
// app.module.ts
@Module({
imports: [
ConfigModule.forRoot(ConfigValidator), // config 설정을 위해 import
TypeOrmModule.forRootAsync({
useClass: MysqlConfigProvider,
}), // mySQL 연결을 위해 import
ScheduleModule.forRoot(), // task scheduling을 위해 import
ReportsModule,
HospitalsModule,
RequestsModule,
],
})
// app.e2e-spec.ts
beforeAll(async () => {
// test용 DB 연결
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [
AppModule,
TypeOrmModule.forRootAsync({
useClass: MysqlConfigProvider,
}), // test db 연결을 위해 import: .env에서 mode === test로 변경해줘야함
],
}).compile();
app = moduleFixture.createNestApplication();
// 기타 pipe, filter 추가
})
그리고 나는 .env에 현재 프로젝트의 mode를 기입하는 변수를 추가해주었는데, 원래는 development
모드였는데 e2e test를 수행할 때는 test
로 변경해주는 식으로 설정해주었다.
// typeORM.config.ts
createTypeOrmOptions(): TypeOrmModuleOptions {
return {
type: 'mysql',
host: this.config.host,
port: this.config.port,
username: this.config.username,
password: this.config.password,
database:
this.config.mode === 'test'
? this.config.test_database
: this.config.database,
entities: [Hospitals, Reports],
synchronize: this.config.mode === 'test',
logging: this.config.mode !== 'production',
};
}
=> test db에 잘 연결이 된 것을 확인하였다.
synchornize: true
를 해주었는데도 truncated가 되지 않았다. synchornize: true
는 entity에서 변경사항이 생길때 이를 실제 DB에 바로 반영을 하는 것이지, 데이터를 삭제하는 건 아니었다. => gpt: synchronize: true
는 기존 데이터베이스의 데이터를 삭제하지는 않습니다. 오직 엔티티 스키마의 변경에 따라 새로운 테이블을 생성하거나 기존 테이블의 구조를 변경하는 역할만 합니다.
그래서, 다음과 같은 옵션을 test 모드일때만 추가될 수 있게 설정하였다.
dropSchema: this.config.mode === 'test',
=> test를 수행할 때마다 테이블 안에 데이터가 다 지워지는 걸 확인하였다.
hospitals table에 직접 쿼리를 써서 값을 집어넣어주려면 repository로 쿼리 메서드에 접근할 수 있으므로 Repository를 import해서 사용하였다.
let hospitalsRepository: Repository<Hospitals>; // Hospitals 데이터를 추가해주는 POST API는 존재하지 않고, DB에 미리 저장해놓기 때문에 직접 db에 접근하기 위해 추가
beforeAll(async () => {
// 설정 코드
// 병원 미리 추가해주기
hospitalsRepository = moduleFixture.get('HospitalsRepository');
await hospitalsRepository.query(`
INSERT INTO hospitals (name, address, phone, available_beds, latitude, longitude)
VALUES ('가톨릭대학교여의도성모병원', '서울특별시 영등포구 63로 10, 여의도성모병원 (여의도동)', '02-3779-1188', 10, 37.51827233800711, 126.93673129599131);
`); // 가용 병상이 있는 병원
await hospitalsRepository.query(`
INSERT INTO hospitals (name, address, phone, available_beds, latitude, longitude)
VALUES ('가톨릭대학교여의도성모병원', '서울특별시 영등포구 63로 10, 여의도성모병원 (여의도동)', '02-3779-1188', 0, 37.51827233800711, 126.93673129599131);
`); // 가용 병상이 없는 병원
=> 병원 데이터가 잘 들어간걸 확인하였다. e2e test code에서 이렇게 하는 방법말고 다른 게 있으면 누가 좀 알려줄분.... ()getConnection()
이라고 typeorm library에서 제공해주는 메서드가 있는데 얘가 db와 연결을 해서 직접 쿼리를 날릴 수 있는 메서드인데 deprecated 되었다... InjectRepository()도 없어지고 얘도 없어지고 암튼 비권장되는 메서드들이 많고 nest가 계속 업데이트되는 최근 라이브러리라 자료가 많지 않다 ㅠ
역시 지니어싀언!! 퍼가여~ ㅋㅋ