5

I have an OpenFeign client set up like this:

@FeignClient(name = "myService", qualifier = "myServiceClient", url = "${myservice.url}")
public interface MyServiceClient {
...
}

and a Spring Boot test set up like this:

@SpringBootTest(webEnvironment = RANDOM_PORT, classes = MyApplication.class)
@RunWith(SpringRunner.class)
@EnableFeignClients(clients = MyServiceClient .class)
public class ReservationSteps {
...
}

The test is supposed to spin up the application and send a request to it using the Feign client.

The problem is the RANDOM_PORT value.

How do I declare the "myservice.url" property in the properties file so it includes the correct port?

I have tried this:

myservice.url=localhost:${local.server.port}

but it results in "localhost:0".

I don't want to use a constant value for the port.

Please help. Thanks!

Lukasz G.
  • 119
  • 1
  • 10

2 Answers2

2

I know this is an old question, but maybe this answer will be helpful to someone


As a workaround, what we can do, is let the host resolving up to Spring Ribbon. You would then configure the host dynamically right before your test starts.

First, add the maven dependency if you don't have it yet

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
   <scope>test</scope>
</dependency>

Then configure your test to run with an 'empty' configuration url for the host, which is the myservice.url property here

@SpringBootTest(webEnvironment = RANDOM_PORT, classes = MyApplication.class)
@RunWith(SpringRunner.class)
@EnableFeignClients(clients = MyServiceClient.class)
@TestPropertySource(properties = "myservice.url=") // this makes sure we do the server lookup with ribbon
public class MyTest {
   ...
}

Then, in a @Before method, all we need to do is provide the service url to ribbon, we can do that with a simple System.setProperty()

public class MyTest {

    @LocalServerPort
    private int port;

    @Before
    public void setup() {
        System.setProperty("MyServiceClient.ribbon.listOfServers", "http://localhost:" + port);
        ...
    }
Naruto Sempai
  • 6,233
  • 8
  • 35
  • 51
Ahmed Sayed
  • 1,429
  • 12
  • 12
0

Another simpler way is to spy the method that is used to resolve the service 's IP. By default, it will call CompositeDiscoveryClient#getInstances() to do that . Together with @LocalServerPort to access the web container port , you can do something like :

@SpringBootTest(webEnvironment = RANDOM_PORT)
public class FooTest {


    @SpyBean
    private CompositeDiscoveryClient compositeDiscoveryClient;

    @LocalServerPort
    private int serverPort;


    @Test
    void test(){
        //call stubResolveMyService() before you invoke any FeignClient 's method
    }


    private void stubResolveMyService(){
        DefaultServiceInstance instance = new DefaultServiceInstance("some-instance" , "myService", "127.0.0.1",serverPort,false);
        when(compositeDiscoveryClient.getInstances("myService")).thenReturn(List.of(instance));
    }

}

It resolves the IP of the service which the service id myService to 127.0.0.1:XXXXX where XXXXX is the random port of the running web container.

Ken Chan
  • 84,777
  • 26
  • 143
  • 172