본문 바로가기

프로젝트/Techfork

[25/12/30] 오늘의 개발 일지 - 테스트 컨테이너 스프링 빈으로 변경

오늘은 통합 테스트 환경을 개선했습니다.

 

기존의 @Testcontainers + @Container 방식은 테스트 코드마다 구현을 해야하므로 재사용성이 높지 않습니다.

또한 스프링 빈의 라이프사이클보다 먼저 컨테이너가 종료될 수 있다는 한계가 있습니다.

 

이를 해결하기 위해 컨테이너를 스프링 빈으로 등록하여 주었습니다.

이 경우 테스트 컨테이너는 스프링 어플리케이션보다 반드시 먼저 시작하고, 뒤늦게 종료됩니다.

 

 

아래는 MySQL 컨테이너 설정입니다.

@TestConfiguration(proxyBeanMethods = false)
public class MySQLTestConfig {
    @Bean
    @ServiceConnection
    MySQLContainer<?> mySQLContainer() {
        return new MySQLContainer<>("mysql:8.0.36");
    }
}

 

@TestConfiguration의 속성으로 들어간 proxyBeanMethods는 프록시 관련 설정입니다.

Configuration은 기본적으로 CGLIB 프록시가 작동하여,

연관이 있는 빈의 경우 프록시를 통해 이미 생성된 싱글톤 빈을 사용할 수 있습니다.

 

하지만 테스트 환경에서는 빈끼리의 연관관계가 존재하지 않으므로,

프록시 생성 비용을 없애기 위해 false로 해주는 것입니다.

 

아래는 Elasticsearch 컨테이너 설정입니다.

@TestConfiguration(proxyBeanMethods = false)
public class ElasticsearchTestConfig {
    @Bean
    @ServiceConnection
    ElasticsearchContainer elasticsearchContainer() {
        return new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.18.0")
                .withEnv("xpack.security.enabled", "false");
    }
}

 

Elasticsearch는 8.x 버전부터는 기본적으로 보안 설정이 있으므로 이를 제거해줍니다.

 

마지막으로 Redis 컨테이너 설정입니다.

@TestConfiguration(proxyBeanMethods = false)
public class RedisTestConfig {

    @Bean
    @ServiceConnection
    RedisContainer redisContainer() {
        return new RedisContainer(DockerImageName.parse("redis:7.2-alpine"));
    }
}

 

 

사용할 때는 다음과 같이 Import를 해주면 사용가능합니다.

@SpringBootTest
@AutoConfigureMockMvc
@Import(MySQLTestConfig.class)
@ActiveProfiles("integrationtest")
class PostControllerIntegrationTest {
   //...
}

 

 

build.gradle을 통해 의존성을 다운로드할 때 주의할 점은

redis는 따로 testcontainers에서 지원하지 않으므로 redis에서 별도로 지원하는 testcontainer 의존성을 받아야 합니다.

testImplementation 'org.testcontainers:mysql:1.21.4'
testImplementation 'org.testcontainers:elasticsearch:1.21.4'
testImplementation 'org.testcontainers:junit-jupiter:1.21.4'
testImplementation 'com.redis:testcontainers-redis:2.2.4'

 

 

참고 자료

https://docs.spring.io/spring-boot/3.5/reference/testing/testcontainers.html#page-title