-
Notifications
You must be signed in to change notification settings - Fork 1
✏️ TypeORM Datasource mock 만들기
분야 | 작성자 | 작성일 |
---|---|---|
BE | 김민수 | 24년 11월 07일 |
TypeORM 0.3버전으로 업데이트되면서 @Transactional
데코레이터가 지원이 중단되었다. 따라서 직접 트랜잭션에 대한 코드를 작성해야했다. 트랜잭션을 반영하는 코드는 2가지 방식이 있지만 이번 프로젝트에서 콜백 기반으로 동작하는 datasource
의 트랜잭션을 사용하기로 했다. QueryRunner
방식을 사용하지 않은 이유는 에러가 발생되는 구간의 try-catch
문과 롤백 그리고 release
에 대한 코드를 작성해야하기 때문에 코드량이 많아지는 문제가 있다고 생각했기 때문에 datasource
방식을 채택했다.
async increaseView(stockId: string) {
await this.datasource.transaction(async (manager) => {
const isExists = await manager.exists(Stock, { where: { id: stockId } });
if (!isExists) {
throw new NotFoundException('stock not found');
}
return await manager.increment(Stock, { id: stockId }, 'views', 1);
});
}
위 코드는 Service 단에서 특정 주식의 조회수를 증가시키는 로직을 datasource
트랜잭션 내부에 동작하도록 한 코드이다. 하지만 위 코드는 단위 테스트하기 어렵다. 왜냐하면 datasource
객체는 db-connection
이 유지해야하는 객체이기 때문에 단위 테스트를 하기 어려운 문제가 있다.
해당 코드가 테스트하기 어려운 이유는 2가지가 있다.
- 비즈니스 로직과 관심사 분리가 제대로 되지 않음
-
datasource
가 DB에 연결되지 않으면 예외가 발생
위 문제에서 비즈니스 로직과 관심사 분리가 제대로 되면 위 문제를 쉽게 해결할 수 있다. 이때 생각한 방법이 repository
단을 두거나, 커스텀 데코레이터를 만드는 것이다. 하지만 첫번째 방법은 DB에 작업을 수행하기 위해 entityManager
를 repository
의 메소드에 파라미터로 계속 전달해야하는 문제가 있고, 두번째 방법은 시간이 오래걸려 제한된 시간동안 다른 기능 구현에 지장이 생길 수 있는 위험이 있다. 결국 첫 번째 문제보다는 두 번째 문제를 해결하면 된다고 생각하게 되었다.
// DataSourceMock을 만드는 함수, managerMock을 전달받는다.
function createDataSourceMock(
managerMock: Partial<EntityManager>,
): Partial<DataSource> {
return {
transaction: jest.fn().mockImplementation(async (work) => {
return work(managerMock);
}),
};
}
const managerMock = {
exists: jest.fn().mockResolvedValue(false),
save: jest.fn().mockResolvedValue(registerRequest),
};
const dataSource = createDataSourceMock(managerMock);
const userService = new UserService(dataSource as DataSource);
위 코드는 Datasource mock
을 만든 후 서비스 객체에 주입하는 코드로 manager
가 수행할 함수를 mock
으로 변형시킨 managerMock
을 받는다.
이후 datasource
의 transaction
함수를 jest.fn().mockImplementation
으로 콜백 함수에 전달되는 manager
를 미리 선언한 mock
객체를 전달하여 동작하도록 코드를 구현했다.
위 방식을 통해서 단위 테스트를 작성할 수 있었다.
- 🚩 FE 기술 선택이유
- ✨ 차트의 반응형 구현과 useRef 타입 문제
- 🐣 부모 요소의 상태에 따라 자식 요소도 스타일 변화 부여하기
- 📁 zod 도입하기
- 🔖 useInfiniteQuery를 사용한 그래프 무한스크롤 구현
- 🎫 사용자의 시점 변화 없는 그래프 스크롤 구현하기
- 🧪 수많은 그래프 데이터 요청을 어떻게 줄일까
- 🌚 다크모드에서 새로고침 시 라이트모드가 잠깐 보이는 문제
- 👊 웹소켓의 채팅 데이터와 REST API의 채팅 데이터를 함께 관리하기
- 📡 BE 기술 선택 이유
- ⛏️ Node WebSocket 파고들기
- ✏️ TypeORM Datasource mock 만들기
- ☁️ oauth ID range 문제
- 📖 custom pipe에서 Nan이 받아지는 문제
- 🪒 nest Websocket에 세션이 안된다고?
- 🏴 nginx websocket 연결 시 문제 발생
- 🆘 WebPush 구현
- 🧊 우선순위 큐로 요청 제어하기
- 🔌 websocket이 늦게 할당되어 발생되는 문제
- 🥳 typeorm을 이용한 FCM 알림 서비스
- 🚦 다중 유저 동시성 제어 ‐ 싱글톤, 뮤텍스
- 🍙 그래프 데이터를 실시간으로 제공하기위한 전략