Tech
Test Containers for Spring Boot
syaku
2023. 10. 13. 18:53
반응형
Test containers for Redis
설치
ext.testcontainersVersion = '1.18.3'
implementation "org.springframework.boot:spring-boot-starter-data-redis"
implementation 'org.apache.commons:commons-pool2:2.11.1'
testImplementation "org.springframework.cloud:spring-cloud-starter-bootstrap"
implementation platform("org.testcontainers:testcontainers-bom:${testcontainersVersion}")
testImplementation 'org.testcontainers:testcontainers'
테스트 컨테이너 초기화
public class RedisTestContainerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final int REDIS_PORT = 6379;
private static final GenericContainer<?> redis = new GenericContainer<>(DockerImageName.parse("redis:7.0.3-alpine"))
.withExposedPorts(REDIS_PORT)
.waitingFor(Wait.forListeningPort());
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
redis.start();
Map<String, Object> properties = new HashMap<>();
properties.put("spring.redis.host", redis.getHost());
properties.put("spring.redis.port", redis.getMappedPort(REDIS_PORT));
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(new MapPropertySource("redis-testcontainer", properties));
}
}
스프링 설정
spring:
redis:
host: localhost
port: 6379
lettuce:
pool:
max-active: 10
max-idle: 10
min-idle: 2
스프링 테스트 코드
@Slf4j
@SpringBootTest
@ContextConfiguration(initializers = RedisTestContainerInitializer.class)
@AutoConfigureMockMvc
class AccessTokenRestControllerTest {
}
Test containers for kafka
설치
ext.testcontainersVersion = '1.18.3'
testImplementation "org.springframework.kafka:spring-kafka-test"
testImplementation "org.springframework.cloud:spring-cloud-starter-bootstrap"
implementation platform("org.testcontainers:testcontainers-bom:${testcontainersVersion}")
testImplementation 'org.testcontainers:kafka'
테스트 컨테이너 초기화
public class KafkaTestContainerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
kafka.start();
Map<String, Object> properties = new HashMap<>();
properties.put("spring.kafka.bootstrap-servers", kafka.getBootstrapServers());
properties.put("spring.kafka.consumer.bootstrap-servers", kafka.getBootstrapServers());
properties.put("spring.kafka.producer.bootstrap-servers", kafka.getBootstrapServers());
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(new MapPropertySource("kafka-testcontainer", properties));
}
}
스프링 설정
spring:
kafka:
bootstrap-servers: localhost:9092
consumer:
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
스프링 테스트 코드
@Slf4j
@SpringBootTest
@ContextConfiguration(initializers = KafkaTestContainerInitializer.class)
class ParkingKafkaProducerTest {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private KafkaProperties kafkaProperties;
@Autowired
private ParkingKafkaProducer parkingKafkaProducer;
@Value("${parking.kafka.parking-topic}")
private String parkingTopic;
private Consumer<String, String> createConsumer() {
Properties properties = new Properties();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getConsumer().getBootstrapServers());
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
return new KafkaConsumer<>(properties);
}
@Test
void send() throws Exception {
ParkingDto dto = ParkingDto.builder()
.enteredAt(LocalDateTime.now())
.vehicleNumber("11가2222")
.entryTid(UUIDGenerator.of())
.build();
parkingKafkaProducer.send(dto);
try (Consumer<String, String> consumer = createConsumer()) {
consumer.subscribe(Collections.singleton(parkingTopic));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
assertFalse(records.isEmpty());
ConsumerRecord<String, String> received = records.iterator().next();
assertEquals(objectMapper.writeValueAsString(dto), received.value());
log.trace("{}", received.value());
}
}
}
[번외] 테스트를 일반적으로 무시하고 필요에 따라 직접 실행하기
// 테스트 코드에 선언
@EnabledIf(expression = "#{environment['spring.profiles.active']?.contains('docker')}", loadContext = true)
// 테스트 실행 설정에서 VM Options 를 추가한다.
-Dspring.profiles.active=test,docker
// grable 테스트 설정 추가한다.
test {
doFirst {
def profiles = System.getProperty('spring.profiles.active') ?: 'test'
systemProperty 'spring.profiles.active', profiles
}
}
참고
반응형