Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to set runtime Local Server Port in Spring Boot Test 1.5

I am using Spring Boot 1.5 for my application. In integration testing I want to fetch the runtime port number of the web server(note: TestRestTemplate is not useful in my case.). There are a few approaches I have tried but none of them seem to work. Below are my approaches.

First Approach

@SpringBootTest(classes = TestConfig.class, webEnvironment =WebEnvironment.DEFINED_PORT)
public class RestServiceTest {

@LocalServerPort      
protected int port;

In my src/main/resources/config/application.properties file I have defined server port as

server.port = 8081

But With this code I am getting error

Could not resolve placeholder 'local.server.port' in value "${local.server.port}"

Second Approach

I have changed

webEnvironment =WebEnvironment.DEFINED_PORT

to

webEnvironment =WebEnvironment.RANDOM_PORT

and in my src/main/resources/config/application.properties file I have defined

server.port = 0

This throws the same as error as the first approach.

Third Approach

In third approach I have tried to use

protected int port;

@Autowired
Environment environment

this.port = this.environment.getProperty("local.server.port");

this returns null value

Fourth Approach

Lastly I have tried to use ApplicationEvents to find out the port number by creating an event listener to listen to EmbeddedServletContainerIntialize

@EventListener(EmbeddedServletContainerInitializedEvent.class)
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
this.port = event.getEmbeddedServletContainer().getPort();
}

public int getPort() {
return this.port;
} 

Added the same to TestConfig

Now, In my test class I have tried use this listener to get the port

@SpringBootTest(classes = TestConfig.class, webEnvironment =WebEnvironment.RANDOM_PORT)
public class RestServiceTest {

protected int port;

@Autowired
EmbeddedServletContainerIntializedEventListener embeddedServletcontainerPort;

this.port = this.embeddedServletcontainerPort.getPort();

this returns 0. Also, I have found out listener event is never triggered.

It is very straight forward as in the docs and other posts but somehow It is not working for me. Help is much appreciated.

like image 789
Meena Chaudhary Avatar asked Apr 19 '17 09:04

Meena Chaudhary


Video Answer


2 Answers

Maybe you forgot to configure the random port for your test web environment.

This should do the trick: @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

Here a test just executed successfully with Spring Boot 1.5.2:

import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RandomPortTests {

    @Value("${local.server.port}")
    protected int localPort;

    @Test
    public void getPort() {
        assertThat("Should get a random port greater than zero!", localPort, greaterThan(0));
    }

}
like image 84
Kevin Peters Avatar answered Sep 23 '22 14:09

Kevin Peters


I had the same issue with an application using spring boot 1.4 and found that the event of EmbeddedServletContainerInitializedEvent is a bit delayed - which means it gets triggered after my bean is initialized -, so in order to resolve this i needed to use lazy annotation on the bean that needs to use the port as for example a RestClient bean and it worked. Example:

@Bean
@Lazy(true)
public RESTClient restClient() {
   return new RESTClient(URL + port)
}
like image 39
Ahmed Ali Avatar answered Sep 25 '22 14:09

Ahmed Ali