e2e 테스트를 하다가 발생한 에러
ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)... Error: DataSource with name "default" has already added.
검색을 하여 찾은 아래의 링크를 따라 해결
https://github.com/Aliheym/typeorm-transactional/issues/10
두가지 해결 방식
방식 1. getDataSourceByName('default') 추가
import { addTransactionalDataSource, getDataSourceByName } from 'typeorm-transactional';
// ...
TypeOrmModule.forRootAsync({
dataSourceFactory: async (options) => {
return getDataSourceByName('default') || addTransactionalDataSource(new DataSource(options));
},
});
방식 2. deleteDataSourceByName('default') 추가
import { addTransactionalDataSource, deleteDataSourceByName } from 'typeorm-transactional';
// ...
TypeOrmModule.forRootAsync({
dataSourceFactory: async (options) => {
deleteDataSourceByName('default');
return addTransactionalDataSource(new DataSource(options));
},
});
각 방식에서 사용된 코드의 의미???
import { DataSource, EntityManager, Repository } from 'typeorm';
...
export type DataSourceName = string | 'default';
const dataSources = new Map<DataSourceName, DataSource>();
export const getDataSourceByName = (name: DataSourceName) => dataSources.get(name);
export const deleteDataSourceByName = (name: DataSourceName) => dataSources.delete(name);
방식 1 을 선택하여 getDataSourceByName('default') 코드를 추가하여 해결
//변경 전
async dataSourceFactory(options) {
if (!options) {
throw new Error('Invalid options passed');
}
return addTransactionalDataSource(new DataSource(options));
},
// 변경 후
async dataSourceFactory(options) {
if (!options) {
throw new Error('Invalid options passed');
}
return getDataSourceByName('default') || addTransactionalDataSource(new DataSource(options));
},
이렇게 하니 귀찮은 일이 발생했다.
1. 앞의 테스트에서 내가 생성한 유저를 다시 생성하려면 이미 있는 e-mail 이라는 문구가 발생
2. 앞의 테스트에서 내가 지운 유저를 또 지우려면 내가 원하는 204가 아니라 500 반환
beforeAll 을 이용하여서 하니
- 옵션< getDataSourceByName('default') >을 추가하지 않아도 해당 에러가 뜨지 않았다. Error: DataSource with name "default" has already added.
- 테스트할때마다 내가 적은 expect 부분을 수정하지 않아도 되었다.
의문점
- beforeEach 에서는 중복이 발생했는데 어떻게 beforeAll 에서는 중복이 발생하지 않을까
-> 데이터베이스를 확인해보니 역시나 중복이 발생. 중복을 방지하기 위해
최종적으로 테이블을 드랍하고 동기화 하는 코드를 추가하여 마무리하였다.
beforeAll(async () => {
initializeTransactionalContext();
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
dataSource = moduleFixture.get<DataSource>(DataSource);
// 데이터베이스 테이블 초기화 및 동기화
await dataSource.dropDatabase();
await dataSource.synchronize();
// 토큰 발행
token = generateTestToken();
app = moduleFixture.createNestApplication();
await app.init();
});
※ 데이테베이스 테이블 초기화를 beforeEach에 사용하면 생성한 유저가 사라져서 jwt 토큰을 발행하는데 문제가 발생한다.