testcontainer로 redis 테스트하기

hyng·2023년 1월 31일
1

smilegate-winter-dev-camp

목록 보기
12/15

프로젝트에서 redis를 테스트할 때 embedded redis(it.ozimov:embedded-redis)를 사용하였었다. 의존성만 추가해 주면 편리하게 사용할 수 있는 장점이 있긴 했지만 여러 문제가 있었다. 여러 스프링 컨텍스트가 실행되면 embedded redis를 새로 실행하려고 하면서 발생하는 포트 충돌 문제, m1 환경에서 발생하는 문제

나중에 언제든 또 다른 문제가 발생할 수도 있다는 생각이 들었고, 버전업을 안할수도 있고 또 지원하지 않는 것들이 있을 수도 있다.
그리고 무엇보다 testcontainer를 사용하면 production과 거의 동일한 테스트 환경을 구축할 수있다.

그래서 testcontainer를 사용하여 테스트하는 방식으로 바꾸기로 했다.
testcontainer를 사용하면 테스트 실행 때마다 특정 컨테이너가 실행되어 테스트를 하고 테스트 이후에 컨테이너가 자동으로 종료된다.

환경: m1, java, junit5, gradle, intellij

다음 링크를 참고하여 build.gradle에 의존성을 추가한다.

    testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
    testImplementation "org.testcontainers:testcontainers:1.17.6"
    testImplementation "org.testcontainers:junit-jupiter:1.17.6"

이제 testcontainer setup 코드를 작성하는데,
테스트 코드와 테스트를 위한 setup 부분을 분리하고 redis container가 필요한 테스트에서 매번 setup 코드를 복사 붙여넣기 하지 않고 재사용 할 수 있도록 별도의 클래스로 분리했다.

public class TestContainerConfig implements BeforeAllCallback {

  private static final String REDIS_IMAGE = "redis:7.0.8-alpine";
  private static final int REDIS_PORT = 6379;
  private GenericContainer redis;

  @Override
  public void beforeAll(ExtensionContext context) {
    redis = new GenericContainer(DockerImageName.parse(REDIS_IMAGE))
      .withExposedPorts(REDIS_PORT);
    redis.start();
    System.setProperty("spring.data.redis.host", redis.getHost());
    System.setProperty("spring.data.redis.port", String.valueOf(redis.getMappedPort(REDIS_PORT
    )));
  }
}

아래 코드 부분이 중요한데, docker에 대해 잘 모르다 보니 이 부분을 빠트리고 돌려 제대로 실행되지 않았다.
구글링을 해보니, expose port를 6379 포트로 설정했다는 것은 로컬의 랜덤 포트를 컨테이너 안 9000포트로 바인딩 한다는 것이기 때문에 컨테이너가 6379포트와 바인딩 한 로컬 포트를 알아서 spring.data.redis.port로 설정해야 한다.
https://stackoverflow.com/questions/58202705/java-testcontainers-cannot-connect-to-exposed-port

    System.setProperty("spring.data.redis.host", redis.getHost());
    System.setProperty("spring.data.redis.port", String.valueOf(redis.getMappedPort(REDIS_PORT
    )));

이렇게 하면 test container 설정은 끝났고 테스트 코드를 작성하면 된다.

@ExtendWith을 사용하여 테스트 실행전에 redis test container가 실행되도록 한다.

테스트를 실행하면 docker container가 생성되는 것을 확인할 수있다.

참고

https://www.baeldung.com/spring-dynamicpropertysource
https://stackoverflow.com/questions/58202705/java-testcontainers-cannot-connect-to-exposed-port
https://www.testcontainers.org/quickstart/junit_5_quickstart/
https://dealicious-inc.github.io/2022/01/10/test-containers.html

profile
공부하고 알게 된 내용을 기록하는 블로그

0개의 댓글