Why we need Testcontainers?
테스트를 위해서는 실제 database가 아닌 환경에서 수행할 필요가 있습니다.
H2를 써도 되지만, 특정 rdb에 특화된 기능을 사용하기 어려운 경우도 있습니다.
대안으로 docker compose로 테스트하기 위한 DB를 같이 띄워도 되지만, 이 역시 관리의 대상이 됩니다.
대신 Testcontainers를 사용하면, 간단하게 외부와 격리된 테스트 환경을 구성할 수 있습니다.
적용법
build.gradle
에 아래의 테스트 의존성을 추가합니다.
MySQL을 사용하는 예시
testImplementation "org.testcontainers:testcontainers:1.19.7"
testImplementation "org.testcontainers:junit-jupiter:1.19.7"
testImplementation "org.testcontainers:jdbc:1.19.7"
testImplementation "org.testcontainers:mysql:1.19.7"
테스트용 Redis 추가
- Redis를 사용하기 위해선 아래의
TestRedisConfig
클래스를 추가합니다.
@TestConfiguration
public class TestRedisConfig {
private static final String REDIS_DOCKER_IMAGE = "redis:7.2.0-alpine";
public TestRedisConfig(RedisProperties redisProperties) {
GenericContainer<?> redisContainer = new GenericContainer<>(DockerImageName.parse(REDIS_DOCKER_IMAGE))
.withExposedPorts(redisProperties.getPort())
.withReuse(true);
redisContainer.start();
redisProperties.setHost(redisContainer.getHost());
redisProperties.setPort(redisContainer.getFirstMappedPort());
}
}
application-test.yml 작성
src/test/resources/application-test.yml
에는 아래와 같이 원하는 MySQL 버전과 Testcontainers 설정을 합니다.
spring.config.activate.on-profile: test # test 프로필에서만 사용하도록 합니다.
spring:
jpa:
hibernate:
ddl-auto: create
show-sql: true
open-in-view: false
defer-datasource-initialization: true
datasource:
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:mysql:8.0.36://test # 원하는 버전 설정
data:
redis:
host: localhost
port: 6379
password: # 공백이어야 합니다.
실제 사용
DataJpaTest
에서 MySQL, Redis 테스트 컨테이너를 사용할 수 있습니다.
@ActiveProfiles("test")
@DataJpaTest
@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // H2 사용 금지
@Import({RedisProperties.class, TestRedisConfig.class})
class MyRepositoryTest {
@Autowired
private SomeEntityRepository someEntityRepository;
}