java - Embedded Redis for Spring Boot

java – Embedded Redis for Spring Boot

java – Embedded Redis for Spring Boot

You can use an embedded Redis like https://github.com/kstyrc/embedded-redis

  1. Add the dependency to your pom.xml
  2. Adjust the properties for your integration test to point to your embedded redis, for example :
    spring:
      redis:
        host: localhost
        port: 6379
    
  3. Instanciate the embedded redis server in a component that is defined in your tests only :
    @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();
        }
    }
    

You can use ozimov/embedded-redis as a Maven(-test)-dependency (this is the successor of kstyrc/embedded-redis).

  1. Add the dependency to your pom.xml
    <dependencies>
      ...
      <dependency>
        <groupId>it.ozimov</groupId>
        <artifactId>embedded-redis</artifactId>
        <version>0.7.1</version>
        <scope>test</scope>
      </dependency>
    
  2. Adjust your application properties for your integration test
    spring.redis.host=localhost
    spring.redis.port=6379
    
  3. Use the embedded redis server in a test configuration
    @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();
      }
    }
    

java – Embedded Redis for Spring Boot

Another neat way is to use the testcontainers library which can run any type of application that can in a Docker container and Redis is no exception. What I like best is that it is lightly coupled with the Spring Test ecosystem.

mavens dependency:

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

simple integration test:

@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);
        }
    }
}

Since Spring Framework 5.2.5 (Spring Boot 2.3.x) you can use the powerful DynamicPropertySource annotation.
Here is an example:

@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);
    }
}

Related posts on java  :

Leave a Reply

Your email address will not be published. Required fields are marked *