체스 5단계는 JDBC api를 사용해서 mysql db와 연동하는 미션입니다.
미션을 수행하면서 가장 핵심적인 고민이 두가지 있었는데요.
- Dao 레이어를 어떻게 테스트할까?
- Service 레이어도 결국 Dao를 사용하는데 여기는 어떻게 테스트 하지?
과거 Spring Boot에 ORM으로 JPA를 사용하는 환경에서는 aop인 @Transactional
애노테이션이 테스트 코드에서는 데이터를 롤백해줬기 때문에 데이터베이스에 테스트용 값이 무차별적으로 들어가는 것을 막을 수 있었습니다.
하지만 JDBC는 그렇지 않죠.
그렇다면 위 두 가지 고민을 왜 하는지 먼저 생각해보겠습니다.
- 운영 db에 무차별적으로 데이터가 들어가는게 싫음
- 제어할 수 없는 상황에 대한 Test를 해야함
제어할 수 없는 상황에 대한 Test는 가짜 객체를 만들어 테스트해 본 경험이 있기 때문에 이를 통해 문제를 해결할 수 있습니다.
그렇다면 이번 포스팅에서는 1번 이슈를 해결하는 방법에 대해 적어보겠습니다.
운영 DB에 데이터를 넣지말고 Test DB를 사용하라
일반적으로 개발을 할 때 로컬 db, dev db, 운영 db 등 사용 목적에 따라 데이터베이스를 달리 사용합니다.
JDBC도 같습니다. 운영 DB에 데이터가 들어가는 게 싫으면 개발용 DB를 만들어서 사용하면 됩니다.
먼저 Connection을 가져오는 유틸 메서드를 하나 생성해봅시다.
외부에서 dev용 db url을 받아 해당 데이터베이스로 connection을 만들 수 있습니다.
개발용 DB url을 가져와 Connection을 만들었습니다. (일반적으로 개발용 db는 사용성이 편한 H2를 많이 쓴다고 하네요, 그런데 무엇을 사용하든 상관은 없습니다.)
테스트 코드를 작성하여 운영용 DB, dev용 DB 모두 잘 연결되는 것을 확인할 수 있습니다.
이제 이 Connection을 이용하여 테스트를 작성해보겠습니다.
하지만 그 전에 주의해야 할 사항이 있습니다.
개발용 DB에 값을 넣지마라
Connection 클래스에는 setAutoCommit()
이라는 메서드가 있습니다.
기본적으로 Connection은 자동 커밋 원칙을 지키고 있는데요, 이 옵션은 트랜잭션이 마무리되면 데이터를 자동으로 커밋하는 역할을 합니다. 에러가 발생하거나, 상황에 따라 롤백을 해야하는 상황에 해당 옵션이 켜져 있으면 문제가 발생하겠죠
저희 개발용 DB에도 데이터가 들어가면 독립적인 환경에서 테스트하기 어려워질 뿐 아니라 테스트를 돌리는 시점마다 코드가 변경되는 문제가 생기겠죠. 한 번 이 문제를 개선해보겠습니다.
개발용 DB와의 Connection을 생성하고 해당 connection의 AutoCommit옵션을 false로 지정해줍니다.
그리고 아래 테스트를 한 번 실행시켜보겠습니다.
h2 포지션의 기물을 white_pawn으로 업데이트 하는 테스트입니다.
테스트는 성공했지만 DB의 값은 변경되지 않은 것을 확인할 수 있습니다.
정리
간단합니다. 개발용 DB를 하나 만들어 해당 DB를 사용하여 테스트하고, Connection의 AutoCommit옵션을 false로 유지하면 됩니다.
이것으로 JDBC 테스트를 수월하게 할 수 있게 됐습니다 ^^
'우아한테크코스 4기 > 레벨1' 카테고리의 다른 글
[레벨 1 돌아보기] OOP에서의 정적 메서드 사용 (0) | 2022.04.11 |
---|---|
[Java] @BeforeEach와 독립적인 단위 테스트 (0) | 2022.04.06 |
[Java] JDBC API Statement vs PreparedStatement (1) | 2022.03.29 |
[Java] Singleton LazyHolder는 왜 Thread safe 한가? (0) | 2022.03.16 |
[Java] 전략패턴 (0) | 2022.03.15 |