레디스를 사용한 통합 테스트

0_0_yoon·2023년 12월 10일
0
post-thumbnail

문제상황

테스트 환경에서 임베디드 레디스를 사용해서 테스트를 진행.
예외 메세지: Unable to connect to Redis
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis

// build.gradle
testImplementation 'it.ozimov:embedded-redis:0.7.2'
// 테스트 코드
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
public class OauthServiceTest {

    @Autowired
    private OauthService oauthService;

    @Test
    void 로그인_한다() {
        final LoginResponse loginResponse = oauthService.login("testCode");
        Assertions.assertThat(loginResponse).usingRecursiveComparison()
                .isNotNull();
    }
}

// ozimov 임베디드 레디스 사용
import redis.embedded.RedisServer;

@Configuration
public class EmbeddedRedisConfig {

    private RedisServer redisServer;

    @PostConstruct
    public void redisServer() {
        redisServer = new RedisServer();
    }

    @PreDestroy
    public void stopRedis() {
        if (redisServer != null) {
            redisServer.stop();
        }
    }
}

원인

ozimov 임베디드 레디스는 arm 아키텍처를 지원하지 않는다.(kstyrc 마찬가지로 지원하지 않는다)

package redis.embedded.util;

public enum Architecture {
    x86,
    x86_64
}

해결

1. 임베디드 레디스를 사용한다.

  1. Apple Silicon 을 지원하는 레디스를 설치한다.
  2. 해당 레디스 바이너리 파일을 프로젝트에 복사한다.
  3. 2 번의 복사한 파일을 임베디드 레디스에 오버라이딩한다.

자세한 방법
장점: 최초 한 번만 레디스를 설치하면 그후에 사용되는 아키텍처(x86, arm)에 영향을 받지 않고
레디스 테스트 환경을 구성할 수 있다.
단점: 임베디드 레디스 라이브러리(ozimov, kstyrc)는 이제 더 이상 서비스되지 않는다.

2. 개발환경에 레디스를 직접 설치한다.

장점: 별도의 라이브러리에 대한 의존성이 없다.
단점: 개발환경에 레디스를 설치해야한다.

3. 개발환경에 도커를 설치후 테스트 컨테이너를 사용한다.

  1. 개발환경에 도커를 설치한 후 실행한다.
  2. 아래 의존성을 추가한다.
// build.gradle
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
  1. testcontainers 와 springframework 에서 지원하는 어노테이션을 적절히 사용한다.
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@Testcontainers // 컨테이너의 생명주기를 자동으로 관리해준다
public class OauthServiceTest {

    @Autowired
    private OauthService oauthService;

    @Container // 사용할 컨테이너를 선언한다
    @ServiceConnection // 컨테이너와의 연결정보를 자동으로 설정해준다, 스프링부트 3.1 이상 부터 지원한다
    static public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:5.0.3-alpine"))
            .withExposedPorts(6379);

    @Test
    void 로그인_한다() {
        final LoginResponse loginResponse = oauthService.login("testCode");
        Assertions.assertThat(loginResponse).usingRecursiveComparison()
                .isNotNull();
    }
}

장점: 확장성이 뛰어나다. 레디스 뿐만 아니라 데이터베이스 또한 별도의 설치없이 테스트 환경을 구축할 수 있기 때문에
단점: 테스트 시간이 비교적 오래걸린다. 로컬에 레디스를 설치해서 테스트 할 경우 평균 0.78 초, 테스트컨테이너 사용시 평균 1.19 초가 걸린다. 52.5% 로 꽤나 차이가 난다.
개발환경에 도커를 설치해야한다.

참고:
https://java.testcontainers.org/quickstart/junit_5_quickstart/
https://spring.io/blog/2023/06/23/improved-testcontainers-support-in-spring-boot-3-1

profile
꾸준하게 쌓아가자

0개의 댓글