서비스 계층을 테스트할 때 @Transactional 사용을 지양하자
이 글은 개인적인 제 생각입니다.
보통 우리는 여러 repository 메서드를를 실행시키는(DB에 접근하는) Service 계층에서 원자성을 보장하기 위해 @Transactional
어노테이션을 붙여줍니다.
트랜잭션 관리는 서비스 계층의 역할 중에서 가장 중요하다고 볼 수도 있는 역할이라고 생각을 하는데요.
단순히 테스트 격리를 위해서 Service 테스트 클래스에서 @Transactional을 붙여주게 된다면 각 서비스 메서드들은 테스트 클래스의 트랜잭션에 참여하게 되기 때문에 서비스 계층의 트랜잭션 관리를 테스트하고 있다고 볼 수 없게 됩니다.
그리고 JPA를 사용한다고 했을 때, 스프링 컨테이너는 기본 전략으로 트랜잭션의 범위와 영속성 컨텍스트의 생존 범위를 같게 하는 전략을 사용하기 때문에, 서비스 계층의 메서드들은 테스트 클래스의 영속성 컨텍스트에 참여하게 되는 것입니다.
만약 서비스 메서드에서 지연 로딩을 위해 트랜잭션이 필요한 상황에 실수로 @Transactional을 붙여주지 않아서 예외가 발생해야 되는 상황인데, 서비스 테스트 클래스의 트랜잭션에 참여하게 된다면 예외가 발생하지 않게 되는 올바르지 않는 테스트를 하고 있을 수도 있는거죠.
그러기 때문에 단순히 테스트 격리를 위해 @Transactional 을 사용하는 것은 지양하는 것이 좋을 것 같습니다. 대안으로 @sql 어노테이션을 이용하거나 EntityManager로 Truncate 쿼리문을 실행시키는 방법이 좋아보입니다.