我在我的机器上使用本地redis-server帮助运行Spring测试案例。
但是我想要一个嵌入式Redis服务器,它不依赖于任何服务器,可以在任何环境中运行,比如H2内存数据库。我该怎么办?
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
@SpringApplicationConfiguration(classes = Application.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MasterIntegrationTest{
}
答案 0 :(得分:39)
您可以使用嵌入式Redis,例如https://github.com/kstyrc/embedded-redis
调整集成测试的属性以指向嵌入式redis,例如:
spring:
redis:
host: localhost
port: 6379
在仅在测试中定义的组件中实现嵌入式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();
}
}
答案 1 :(得分:17)
您可以使用ozimov/embedded-redis作为Maven(-test)-dependency(这是kstyrc/embedded-redis的继承者)。
将依赖项添加到pom.xml
<dependencies>
...
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.7.1</version>
<scope>test</scope>
</dependency>
调整集成测试的应用程序属性
spring.redis.host=localhost
spring.redis.port=6379
@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();
}
}
答案 2 :(得分:5)
另一种巧妙的方法是使用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:3.0.6").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);
}
}
}
答案 3 :(得分:2)
你可以看到这个存储库:https://github.com/caryyu/spring-embedded-redis-server,与Spring和Spring Boot完全集成
<dependency>
<groupId>com.github.caryyu</groupId>
<artifactId>spring-embedded-redis-server</artifactId>
<version>1.1</version>
</dependency>
@Bean
public RedisServerConfiguration redisServerConfiguration() {
return new RedisServerConfiguration();
}
spring:
redis:
port: 6379
embedded: true