マシン上のローカル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を使用できます
統合テストのプロパティを調整して、埋め込み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();
}
}
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
テスト構成 で埋め込み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();
}
}
もう1つの便利な方法は、Dockerコンテナーで実行可能なあらゆるタイプのアプリケーションを実行できるtestcontainers
ライブラリーを使用することです。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);
}
}
}
このリポジトリを見ることができます: 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