2016-08-16 64 views
1

我能夠獲得Spring Boot集成以生成隨機自由端口以啓動自身。但是我還需要一個Redis的免費端口。Spring Boot集成測試隨機免費端口

@ContextConfiguration(classes = {MyApplication.class}, loader = SpringApplicationContextLoader.class) 
@WebIntegrationTest(randomPort = true, value = "server.port:0") 
@ActiveProfiles(profiles = {"local"}) 
public class SegmentSteps { 

    private static final String HOST_TEMPLATE = "http://localhost:%s"; 

    // Needs to be a random open port 
    private static final int REDIS_PORT = 6380; 

    private String host; 
    @Value("${local.server.port}") 
    private int serverPort; 

    private RedisServer redisServer; 

    @Before 
    public void beforeScenario() throws Exception { 
     host = String.format(HOST_TEMPLATE, serverPort); 
     redisServer = RedisServer.builder() 
       .redisExecProvider(RedisExecProvider.defaultProvider()) 
       .port(REDIS_PORT) 
       .setting("bind 127.0.0.1") 
       .build(); 
     redisServer.start(); 
    } 

    ... 
} 

有關如何實現此目的的任何想法?

回答

7

您可以使用Spring框架的SocketUtils得到一個可用的端口:

int redisPort = SocketUtils.findAvailableTcpPort(); 
+0

是有沒有辦法在上下文中獲得相同的數字? – ptimson

+0

或者我只是使用一個int bean?有限定符? – ptimson

+0

@ptimson,我不明白你的問題。你能詳細說明一下嗎? – mre

0

您還可以通過或者使用您選擇的Java客戶端或通過利用Overcast運行中泊塢你的Redis。如果使用陰天,通過激活exposeAllPorts選項,您的Redis將綁定到主機上的隨機端口。

至於如何啓用在上下文中的屬性 - 這需要一些工作,但你可以實現將啓動Docker容器偵聽器,並把港口作爲屬性的環境:

public class IntegrationTestBootstrapApplicationListener implements 
    ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { 

    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 4; 
    public static final int PROPERTY_SOURCE_NAME = "integrationTestProps"; 

    private int order = DEFAULT_ORDER; 

    public void setOrder(int order) { 
     this.order = order; 
    } 

    @Override 
    public int getOrder() { 
     return this.order; 
    } 

    @Override 
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { 
     ConfigurableEnvironment environment = event.getEnvironment(); 

     if (!environment.getPropertySources().contains(PROPERTY_SOURCE_NAME)) { 
      CloudHost itestHost = CloudHostFactory.getCloudHost("redis"); 
      itestHost.setup(); 

      String host = itestHost.getHostName(); 
      // fetch the dynamic port from Docker 
      int port = itestHost.getPort(6379); 

      // alternatively, skip the whole CloudHost setup above and just use: 
      // int port = SocketUtils.findAvailableTcpPort(); 

      environment.getPropertySources().addLast(
       new MapPropertySource(
       PROPERTY_SOURCE_NAME, Collections.<String, Object> singletonMap(
        "redis.port", port)); 
      ); 
     } 
    } 

} 
+0

偉大的將不得不放棄這個項目 - 可能會讓這個項目變得過度 – ptimson

+0

是的,想通了,但是如果你需要配置幾個外部資源(比如Redis,RabbitMQ,PostgreSQL和FTP服務器),這是一個很好的選擇。 –