@DataJpaTest (인메모리 DB, e.g., H2):
@SpringBootTest (로컬/개발 DB 연결):
Testcontainers는 JUnit 테스트 코드 내에서 Docker 컨테이너를 프로그래매틱하게 생성하고 관리할 수 있게 해주는 Java 라이브러리입니다.
핵심 아이디어: 테스트가 실행될 때마다, 필요한 소프트웨어(DB, Redis, Kafka 등)가 설치된 Docker 컨테이너를 즉석에서 띄우고, 테스트가 끝나면 컨테이너를 자동으로 파기(destroy)합니다.
@SpringBootTest와 Testcontainers를 이용한 통합 테스트@SpringBootTest의 "실제 환경과 유사함"이라는 장점과, Testcontainers의 "환경 독립성 및 격리"라는 장점을 결합하여, 가장 이상적인 데이터베이스 통합 테스트 환경을 구축할 수 있습니다.의존성 추가: build.gradle에 testcontainers와 사용할 데이터베이스(e.g., mysql)에 대한 의존성을 추가합니다.
테스트 컨테이너 설정:
@SpringBootTest가 붙은 테스트 클래스에 @Testcontainers 어노테이션을 추가하여 Testcontainers 기능을 활성화합니다.@Container 어노테이션을 사용하여, 테스트 중에 실행할 Docker 컨테이너를 정의합니다.@DynamicPropertySource: Testcontainers가 동적으로 생성한 컨테이너의 접속 정보(JDBC URL, username, password)를 Spring Boot의 application.yml 설정값에 런타임에 주입하는 매우 중요한 역할을 합니다.@SpringBootTest
@Testcontainers // Testcontainers 활성화
class PostRepositoryIntegrationTest {
// static으로 선언하여 클래스 내 모든 테스트에서 컨테이너를 공유 (속도 향상)
@Container
static MySQLContainer<?> mySQLContainer = new MySQLContainer<>("mysql:8.0");
// 동적으로 생성된 컨테이너의 접속 정보를 Spring 설정에 주입
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", mySQLContainer::getJdbcUrl);
registry.add("spring.datasource.username", mySQLContainer::getUsername);
registry.add("spring.datasource.password", mySQLContainer::getPassword);
}
@Autowired
private PostRepository postRepository;
@Test
@DisplayName("게시글 저장 및 조회 통합 테스트")
void saveAndFindPost() {
// given
Post newPost = new Post("테스트 제목", "테스트 내용");
// when
Post savedPost = postRepository.save(newPost);
Optional<Post> foundPost = postRepository.findById(savedPost.getId());
// then
// 이 테스트는 실제 MySQL 8.0 Docker 컨테이너 위에서 실행됨
assertThat(foundPost).isPresent();
assertThat(foundPost.get().getTitle()).isEqualTo("테스트 제목");
}
}
테스트 실행:
@DynamicPropertySource가 컨테이너의 동적 포트와 자격 증명을 Spring의 DataSource 설정에 덮어씁니다.@SpringBootTest는 이 설정으로 Spring 컨테이너를 구동하고, 실제 DB 커넥션을 맺습니다.@DataJpaTest는 빠르지만 운영 환경과의 차이라는 한계가 있고, 실제 DB를 사용하는 @SpringBootTest는 환경 의존성과 격리에 어려움이 있습니다.@SpringBootTest와 Testcontainers를 함께 사용하면, @DynamicPropertySource를 통해 동적으로 생성된 DB 컨테이너의 접속 정보를 Spring에 주입하여, 신뢰도 높고 재현 가능한 데이터베이스 통합 테스트를 작성할 수 있습니다.