본문 바로가기
우아한테크코스 4기/레벨1

[Java] db 테스트

by 나는후니 2022. 4. 2.

체스 5단계는 JDBC api를 사용해서 mysql db와 연동하는 미션입니다.

미션을 수행하면서 가장 핵심적인 고민이 두가지 있었는데요.

  1. Dao 레이어를 어떻게 테스트할까?
  2. Service 레이어도 결국 Dao를 사용하는데 여기는 어떻게 테스트 하지?

과거 Spring Boot에 ORM으로 JPA를 사용하는 환경에서는 aop인 @Transactional 애노테이션이 테스트 코드에서는 데이터를 롤백해줬기 때문에 데이터베이스에 테스트용 값이 무차별적으로 들어가는 것을 막을 수 있었습니다.

하지만 JDBC는 그렇지 않죠.

 

그렇다면 위 두 가지 고민을 왜 하는지 먼저 생각해보겠습니다.

  1. 운영 db에 무차별적으로 데이터가 들어가는게 싫음
  2. 제어할 수 없는 상황에 대한 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 테스트를 수월하게 할 수 있게 됐습니다 ^^