設置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,存在大量的冗餘。其實可以利用BeanFactoryPostProcessorApplicationListener接口實現

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);          }      }  }