[java] TestContainers를 사용하여 서비스 디스커버리 테스트하기

서비스 디스커버리는 분산 시스템에서 사용되는 중요한 구성 요소입니다. 이는 서비스 간 통신 및 연결을 쉽게 만들어주는 것이며, 서비스가 동적으로 등록 및 발견 될 수 있도록 합니다.

이번 블로그 포스트에서는 TestContainers를 사용하여 서비스 디스커버리 테스트를 수행하는 방법을 알아보겠습니다. TestContainers는 독립적인 컨테이너 환경을 프로그래밍으로 생성하고 관리하는 라이브러리입니다.

1. 의존성 추가

먼저 Maven 또는 Gradle 프로젝트에 TestContainers 의존성을 추가해야합니다. 아래는 Maven의 예입니다.

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>1.16.0</version>
    <scope>test</scope>
</dependency>

2. Service Discovery 컨테이너 설정

다음으로 테스트에서 사용할 Service Discovery 컨테이너를 설정해야합니다. 예를 들어, 여기서는 Docker 컨테이너를 사용합니다.

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;

public class ServiceDiscoveryTest {

    private static final int SERVICE_DISCOVERY_PORT = 8500;

    @Container
    private static final GenericContainer<?> serviceDiscoveryContainer =
            new GenericContainer<>(DockerImageName.parse("consul:latest"))
                    .withExposedPorts(SERVICE_DISCOVERY_PORT);

    // 테스트 코드 작성
}

위 코드에서 consul:latest 이미지로 컨테이너를 생성하고 8500 포트를 노출시켰습니다.

3. Service Discovery 통합 테스트

이제 Service Discovery와 상호 작용하는 테스트 코드를 작성할 수 있습니다. 아래는 예시입니다.

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.ContextConfiguration;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(initializers = {ServiceDiscoveryTest.Initializer.class})
public class ServiceDiscoveryTest {

    private static final int SERVICE_DISCOVERY_PORT = 8500;

    @Container
    private static final GenericContainer<?> serviceDiscoveryContainer =
            new GenericContainer<>(DockerImageName.parse("consul:latest"))
                    .withExposedPorts(SERVICE_DISCOVERY_PORT);

    // 로컬 지정 포트 사용
    @LocalServerPort
    private int port;

    @Test
    public void testServiceRegistration() {
        // Service Discovery에 서비스 등록

        // 등록한 서비스에 대한 검증 로직 작성
    }

    // Service Discovery 컨테이너 초기화
    public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            TestPropertyValues.of(
                    "spring.cloud.consul.host=" + serviceDiscoveryContainer.getContainerIpAddress(),
                    "spring.cloud.consul.port=" + serviceDiscoveryContainer.getMappedPort(SERVICE_DISCOVERY_PORT)
            ).applyTo(configurableApplicationContext.getEnvironment());
        }
    }

}

위 코드에서는 @Container 어노테이션을 사용하여 Service Discovery 컨테이너를 생성하고, @LocalServerPort 어노테이션을 사용하여 테스트 중인 서버에 할당된 임의의 포트를 가져옵니다.

테스트 메소드 내에 필요한 로직을 작성하고 Service Discovery에 서비스를 등록한 후, 등록한 서비스에 대한 검증 로직을 작성합니다.

4. 테스트 수행

모든 설정이 완료되었으므로 테스트를 실행해 볼 차례입니다. ServiceDiscoveryTest 클래스에 @Test 어노테이션이 지정된 메소드를 추가하고, IDE나 빌드 도구에서 해당 테스트를 실행하면 됩니다.

마무리

이번 블로그 포스트에서는 TestContainers를 사용하여 서비스 디스커버리 테스트를 수행하는 방법을 알아보았습니다. TestContainers를 활용하면 독립적인 환경에서 테스트를 수행할 수 있으며, 이를 통해 서비스 디스커버리를 포함한 다양한 기술을 테스트할 수 있습니다.