programing

스프링 부트용 임베디드 레디스

golfzon 2023. 3. 10. 23:02
반응형

스프링 부트용 임베디드 레디스

머신상의 로컬 Redis 서버의 도움을 받아 Spring Boot 통합 테스트 케이스를 실행합니다.

단, 어떤 서버에도 의존하지 않고 H2 인메모리 데이터베이스 등 어떤 환경에서도 실행할 수 있는 임베디드 Redis 서버를 원합니다.어떻게 해야 하죠?

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
@SpringApplicationConfiguration(classes = Application.class) 
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MasterIntegrationTest {

}

https://github.com/kstyrc/embedded-redis과 같은 임베디드 Redis를 사용할 수 있습니다.

  1. pom.xml에 의존관계를 추가합니다.
  2. 삽입된 redis를 가리키도록 연동 테스트 속성을 조정합니다.다음은 예를 제시하겠습니다.

    spring:
      redis:
        host: localhost
        port: 6379
    
  3. 테스트에서만 정의된 컴포넌트에 내장된 redis 서버를 설치합니다.

    @Component
    public class EmbededRedis {
    
        @Value("${spring.redis.port}")
        private int redisPort;
    
        private RedisServer redisServer;
    
        @PostConstruct
        public void startRedis() throws IOException {
            redisServer = new RedisServer(redisPort);
            redisServer.start();
        }
    
        @PreDestroy
        public void stopRedis() {
            redisServer.stop();
        }
    }
    

ozimov/embedded-redis는 Maven(-test) 의존관계로 사용할 수 있습니다(이것은 kstyrc/embedded-redis의 후속입니다).

  1. pom.xml에 의존관계를 추가합니다.

    <dependencies>
      ...
      <dependency>
        <groupId>it.ozimov</groupId>
        <artifactId>embedded-redis</artifactId>
        <version>0.7.1</version>
        <scope>test</scope>
      </dependency>
    
  2. 통합 테스트용 응용 프로그램 속성 조정

    spring.redis.host=localhost
    spring.redis.port=6379
    
  3. 테스트 구성에서 내장된 redis 서버 사용

    @TestConfiguration
    public static class EmbededRedisTestConfiguration {
    
      private final redis.embedded.RedisServer redisServer;
    
      public EmbededRedisTestConfiguration(@Value("${spring.redis.port}") final int redisPort) throws IOException {
        this.redisServer = new redis.embedded.RedisServer(redisPort);
      }
    
      @PostConstruct
      public void startRedis() {
        this.redisServer.start();
      }
    
      @PreDestroy
      public void stopRedis() {
        this.redisServer.stop();
      }
    }
    

도커 컨테이너에서 실행할 수 있는 모든 유형의 응용 프로그램을 실행할 수 있는 테스트 컨테이너 라이브러리를 사용하는 것도 좋은 방법입니다.Redis도 예외는 아닙니다.내가 가장 좋아하는 것은 스프링 테스트 생태계와 가볍게 결합되어 있다는 것이다.

maven 의존성:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>${testcontainers.version}</version>
</dependency>

간단한 통합 테스트:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"management.port=0"})
@ContextConfiguration(initializers = AbstractIntegrationTest.Initializer.class)
@DirtiesContext
public abstract class AbstractIntegrationTest {

    private static int REDIS_PORT = 6379;

    @ClassRule
    public static GenericContainer redis = new GenericContainer("redis:5-alpine").withExposedPorts(REDIS_PORT);

    public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext ctx) {
            // Spring Boot 1.5.x
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(ctx,
                "spring.redis.host=" + redis.getContainerIpAddress(),
                "spring.redis.port=" + redis.getMappedPort(REDIS_PORT));

            // Spring Boot 2.x.
            TestPropertyValues.of(
                "spring.redis.host:" + redis.getContainerIpAddress(),
                "spring.redis.port:" + redis.getMappedPort(REDIS_PORT))
                .applyTo(ctx);
        }
    }
}

Spring Framework 5.2.5 (Spring Boot 2.3.x)이후로 강력한DynamicPropertySource주석입니다.다음은 예를 제시하겠습니다.

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public abstract class AbstractIT {

    static GenericContainer redisContainer = new GenericContainer("redis:5-alpine").withExposedPorts(6379);

    @DynamicPropertySource
    static void properties(DynamicPropertyRegistry r) throws IOException {
        r.add("spring.redis.host", redisContainer::getContainerIpAddress);
        r.add("spring.redis.port", redisContainer::getFirstMappedPort);
    }
}

다음 저장소를 볼 수 있습니다.https://github.com/caryyu/spring-embedded-redis-server 는 스프링 및 스프링 부트와 완전히 통합되어 있습니다.

메이브 의존성

<dependency>
<groupId>com.github.caryyu</groupId>
<artifactId>spring-embedded-redis-server</artifactId>
<version>1.1</version>
</dependency>

스프링 부트 주석

@Bean
public RedisServerConfiguration redisServerConfiguration() {
return new RedisServerConfiguration();
}

application.yml 사용방법

spring:
    redis:
        port: 6379
        embedded: true

스프링과 리액티브를 사용하여 redisactive로 데이터에 액세스하는 경우.그 말은, 당신이 지금ReactiveRedisConnectionFactory(와 함께)RedisConnectionFactorybean)과LettuceConnectionFactory그런 다음 이 방법을 사용하여 여러 테스트 클래스에 대해 포함된 redis를 설정할 수 있습니다.

우선 의존관계에 Playtika 삽입 redis를 추가합니다.

dependencies {
    testCompile("com.playtika.testcontainers:embedded-redis:2.0.9")
}

다음으로 redis 호스트와 포트를embedded.redisapplication.yml(작성 시 env 변수로 삽입된 redis에 의해 생성됩니다).

spring:
  redis:
    host: \${embedded.redis.host:localhost}
    port: \${embedded.redis.port:6739}

bootstrap-redisnoauth.properties파일, env 변수 설정embedded.redis.requirepass=false패스워드를 필요로 하지 않도록 합니다.

다음으로 테스트에서 액티브프로파일을 사용합니다.

@ActiveProfiles("redisnoauth")

그리고 이거 꼭 챙겨서@TestConfiguration랜덤하게 생성된 포트로 생성된redis에 접속할 수 있도록 테스트클래스에서도 사용합니다.

@Category(IntegrationTest.class)
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("redisnoauth")
public class RedisCacheTest {

    @TestConfiguration
    static class RedisTestConfiguration {
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory(@Value("${spring.redis.host}") String host,
                                                             @Value("${spring.redis.port}") int port) {
            return new LettuceConnectionFactory(host, port);
        }
    
        @Bean
        public RedisOperations<String, String> stringKeyAndStringValueRedisOperations(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(new StringRedisSerializer(UTF_8));
            redisTemplate.setValueSerializer(new StringRedisSerializer(UTF_8));
            return redisTemplate;
        }
    }

    @Test
    public void myTest() {
      // your test
    }

}

그리고 원활하게 작동해야 합니다.

언급URL : https://stackoverflow.com/questions/32524194/embedded-redis-for-spring-boot

반응형