title: How to set MockWebServer port to WebClient in JUnit test?
body: <p>I'm using <code>spring-boot</code> with <code>WebClient</code>, which is autowired as a bean.</p>
  
  <p>Problem: when writing a <code>junit</code> integration test, I have to use okhttp <code>MockWebServer</code>. This mock always starts up on a random port, eg <code>localhost:14321</code>.</p>
  
  <p>Now my <code>WebClient</code> of course has a fixed url that it sends the requests to. This url may be given by an <code>application.properties</code> parameter like <code>webclient.url=https://my.domain.com/</code>, so I could override that field in a <code>junit</code> test. But only statically.</p>
  
  <p>Question: how can I reset the <code>WebClient</code> bean inside a <code>@SpringBootTest</code> so that it sends the requests always to my mock server?</p>
  
  <pre><code>@Service
  public class WebClientService {
       public WebClientService(WebClient.Builder builder, @Value("${webclient.url}" String url) {
            this.webClient = builder.baseUrl(url)...build();
       }
  
       public Response send() {
            return webClient.body().exchange().bodyToMono();
       }
  }
  
  @Service
  public void CallingService {
        @Autowired
        private WebClientService service;
  
        public void call() {
             service.send();
        }
  }
  
  
  @RunWith(SpringRunner.class)
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  public class MyWebTest {
          @Autowired
          private CallingService calling;
  
          @Test
          public void test() {
               MockWebServer mockWebServer = new MockWebServer();
               System.out.println("Current mock server url: " + mockWebServer.url("/").toString()); //this is random    
  
               mockWebServer.enqueue(new MockResponse()....);
  
               //TODO how to make the mocked server url public to the WebClient?
               calling.call();
          }
  }
  </code></pre>
  
  <p>As you see, I'm writing a full realworld junit integration test. The only problem is: how can I pass the <code>MockWebServer</code> url and port to the <code>WebClient</code> so that it automatically sends the requests to my mock??</p>
  
  <p>Sidenote: I definitely need a random port in <code>MockWebServer</code> here to not interfer with other running tests or applications. Thus have to stick to the random port, and find a way to pass it to the webclient (or dynamically override the application property).</p>
  
  <hr>
  
  <p><strong>Update</strong>:
  I came up with the following, which works. But maybe anyone knows how to make the mockserver field <em>non-static</em>?</p>
  
  <pre><code>@ContextConfiguration(initializers = RandomPortInitializer.class)
  public abstract class AbstractITest {
      @ClassRule
      public static final MockWebServer mockWebServer = new MockWebServer();
  
      public static class RandomPortInitializer implements ApplicationContextInitializer&lt;ConfigurableApplicationContext&gt; {
          @Override
          public void initialize(ConfigurableApplicationContext applicationContext) {
              TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
                      "webclient.url=" + mockWebServer.url("/").toString());
          }
      }
  }
  </code></pre>