繁体   English   中英

用于 Spring Boot 的嵌入式 Redis

[英]Embedded Redis for Spring Boot

我在我机器上的本地 Redis 服务器的帮助下使用 Spring Boot 运行我的集成测试用例。

但是我想要一个不依赖于任何服务器并且可以在任何环境中运行的嵌入式 Redis 服务器,例如 H2 内存数据库。 我该怎么做?

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

}

您可以使用嵌入式 Redis,如https://github.com/kstyrc/embedded-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(); } }

另一个巧妙的方法是使用testcontainers库,它可以运行任何类型的应用程序,它可以在 Docker 容器中运行,Redis 也不例外。 我最喜欢的是它与 Spring Test 生态系统的结合。

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 ,与 Spring 和 Spring Boot 完全集成

Maven 依赖

<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

如果您使用 spring 和reactive 来通过redis访问数据 这意味着您有一个ReactiveRedisConnectionFactory (带有一个RedisConnectionFactory bean)和一个LettuceConnectionFactory那么您可能希望按照这种方法为多个测试类设置嵌入式 redis。

首先将playtika 嵌入的 redis添加到您的依赖项中:

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

然后设置Redis的主机和端口作为embedded.redis一个在你的application.yml(由嵌入式Redis的作为创作环境变量产生)。

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

bootstrap-redisnoauth.properties文件中,设置环境变量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
    }

}

它应该工作顺利。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM