Test code for SpringBoot multi-module with Redis
Test code environment in SpringBoot multi-module project with Redis utilized in a child module.
In multi-module system, setting up environment for integration test code can be pain in the ass.
Especially, when the child module uses database connection.
For testing environment, temporary database should be up and running for (relatively)short period of time and down after when test is done.
Embedded redis can be an option if your child module uses redis.
In gradle, testFixture can be used for parent module to exploit configuration of child module.
Let’s say that parent module is called ‘A’ and child module is called ‘B’.
As shown below, testFixture should be set up in build.gradle file of module B.
plugins {
id "java-test-fixtures"
}
dependencies {
testFixturesImplementation 'org.springframework.boot:spring-boot-starter-data-redis'
testFixturesImplementation group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'
testFixturesImplementation ('org.springframework.boot:spring-boot-starter-web') // include if your module does not use it on implementation
}
Now, it should be included in build.gradle file of module A.
dependencies {
testImplementation(testFixtures(project(':B')))
}
After setting up for build.gradle, it’s time to write code for embedded redis up and running.
Following two classes should be configured under testFixtures path in module B.
@Import(TestRedisConfig.class)
@Configuration("redisTest")
public class EmbeddedRedis {
@Value("${spring.redis.port}")
private int port;
private RedisServer redisServer;
@PostConstruct
public void startRedis() {
this.redisServer = new RedisServer(port);
this.redisServer.start();
}
@PreDestroy
public void stopRedis() {
if (redisServer != null) {
this.redisServer.stop();
}
}
}
@DependsOn("redisTest")
@Configuration
public class TestRedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Primary
@Bean
public RedisConnectionFactory testLettuceConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Primary
@Bean
public StringRedisTemplate testStringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
return stringRedisTemplate;
}
}
In TestRedisConfig class, DependsOn annotation is used to prevent LettuceConnectionFactory creation before the embedded redis running.
The primary annotation is added to prevent multiple bean error, since the configuration for actual server also exist in main directory.
Please make sure that you have configured spring.redis.hot and port properly in your yml or properties file under testFixtures/resources directory.
Module A should import the configuration above.
@SpringBootTest(
classes = {EmbeddedRedis.class},
properties = "spring.profiles.active:b-test"
)
public class ParentTest {
}
Note that properties option configured properly with the name of yml file in module B.
In this case, application-b-test.yml should be the name of the yml file in module B.
This article was created by Crocoder7. It is not to be copied without permission.
Leave a comment