設置Spring單元測試的外部依賴
- 2019 年 12 月 2 日
- 筆記
單元測試中,有時候也依賴外部的組件,比如Redis-Mock。Spring Boot Test需要在上下文啟動之前,先啟動Redis-Mock,否則上下文會啟動失敗
依賴的外部組件
比如單元測試中依賴redis-mock,就必須在Spring上下文下載之前就先啟動Redis Server,否則就會報下面的錯誤
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:6379
方法一:在每個Specification中配置RedisServer
@SpringBootTest @ActiveProfiles("unittest") @Transactional class OrderManagerTest extends Specification { private static RedisServer redisServer = null def "setupSpec"() { try { redisServer = RedisServer.newRedisServer() redisServer.start() System.setProperty("spring.redis.port", Integer.toString(redisServer.getBindPort())) } catch (IOException e) { throw new RuntimeException(e) } } def "cleanupSpec"() { if (redisServer != null) { redisServer.stop() } } }
更好的方法
上面方法,需要在每個Specification都配置Redis Server,存在大量的冗餘。其實可以利用BeanFactoryPostProcessor
和ApplicationListener
介面實現
import com.github.tenmao.redismock.RedisServer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ApplicationContextEvent; import org.springframework.context.event.ContextClosedEvent; import org.springframework.stereotype.Component; import java.io.IOException; @Component public class UnittestCustomContext implements BeanFactoryPostProcessor, ApplicationListener<ApplicationContextEvent> { private static RedisServer redisServer = null; @Override public void onApplicationEvent(ApplicationContextEvent event) { if (event instanceof ContextClosedEvent) { //Spring上下文結束後清理自定義上下文 System.out.println("tenmao unit test for event: " + event); if (redisServer != null) { redisServer.stop(); } } } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { try { //Spring上下文初始化之前 配置自定義上下文,也可以修改Spring配置資訊 redisServer = RedisServer.newRedisServer(); redisServer.start(); System.setProperty("spring.redis.port", Integer.toString(redisServer.getBindPort())); } catch (IOException e) { throw new RuntimeException(e); } } }