使用Spring进行集成测试时如何控制@PostConstruct

时间:2015-10-10 08:50:34

标签: java spring unit-testing spring-boot integration-testing

我有Spring bean类RedisRepo 我正在使用@PostConstruct初始化我的数据库连接:

 @PostConstruct
    public void init() {
        logger.debug("RedisRepo, Init.");
        client = new RedisClient(REDIS_HOST, REDIS_PORT);
        ...
    }

我在SpringConfiguration.class使用java配置创建这个bean:

 @Bean
    @Scope("singleton")
    public RedisRepo redisjRepo() {
        return new RedisRepo();
    }

我开始使用Spring构建集成测试。 我使用相同的配置类(SpringConfiguration.class)进行测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringConfiguration.class)

我的Test类使用embedded-redis所以我需要在开始测试之前启动它:

 @Before
    public void init() throws IOException {
//init embedded-redis
}

问题是当我开始测试时,在我的集成测试init()类(过去的下面)之前执行的RedisRepo类的@PostConstruct导致我为null,因为我的嵌入式redis还没有初始化。

我怎么能避免它? Mybe我没有做对吗?

谢谢, 射线。

1 个答案:

答案 0 :(得分:1)

我建议考虑使用spring Boot自动配置(@EnableAutoConfiguration@SpringBootApplication)来初始化Redis连接。您可以使用这些Spring Boot properties自定义Redis:

# REDIS (RedisProperties)
spring.redis.database= # database name
spring.redis.host=localhost # server host
spring.redis.password= # server password
spring.redis.port=6379 # connection port
spring.redis.pool.max-idle=8 # pool settings ...
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.sentinel.master= # name of Redis server
spring.redis.sentinel.nodes= # comma-separated list of host:port pairs

这将消除@PostConstruct生产代码中连接初始化的需要,您可以从上下文粉尘测试中自动装配Redis相关bean。

<强> EDIT1:

要在测试方法之前填充Redis实例,您可以使用@BeforeMethod(使用TestNg)或@Before(使用JUnit)。要在测试之前填充它,但在初始化上下文之后,在测试类中使用@PostConstruct。

<强> EDIT2:

您询问了通用规则如何克服@PostConstruct中资源初始化的需求。我相信您的问题是如何在应用程序中布线bean。

您的@PostConstruct初始化在其他bean中完成,其中RedisClient存储为变量client。我认为这很可能是关注的焦点。如果以这种方式将RedisClient bean注册到spring上下文中:

@Bean
public RedisClient redisClient() {
    RedisClient client = new RedisClient(REDIS_HOST, REDIS_PORT);
    ...
    return client;
}

您可以将其自动装入已进行@PostConstruct初始化的bean中。您还可以在测试期间自动装配它。如果RedisClient不是线程安全的,您可能需要考虑原型或请求范围。

使用这种方法,我极少使用@PostConstruct并使用Spring IoC容器来处理所有可重用的资源实例。