Set property with wiremock random port in spring boot test

Consider using Spring Cloud Contract Wiremock

There is already a JUnit Rule builder which allows to specify ${wiremock.port} to set random port in property/yaml files

Or you can use WireMockRestServiceServer to bind WireMock to your RestTemplate so you don't even need to override URLs in your tests.


Use property substitution in your application.properties:

external.baseUrl=http://exampleUrl:${wiremock.server.port}

This requires the wiremock.server.port property to be set before the SpringBootTest is initialised, which can be achieved by adding the @AutoConfigureWireMock annotation to your test class.


The property name mentioned in https://stackoverflow.com/a/48859553/309683 (i.e. wiremock.port) is not correct, at least since Spring Cloud Contract version 2.1.2.RELEASE.

1. Working example

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
public class PortServiceTest {

    @Autowired
    private Environment environment;

    @Test
    public void shouldPopulateEnvironmentWithWiremockPort() {
        assertThat(environment.containsProperty("wiremock.server.port")).isTrue();
        assertThat(environment.getProperty("wiremock.server.port")).matches("\\d+");
    }

}

2. Other WireMock properties

Other than wiremock.server.port, @AutoConfigureWireMock populates the environment with some other properties too:

  1. wiremock.server.https-port
  2. wiremock.server.stubs[]
  3. wiremock.server.files[]

3. Gradle dependencies

To use Spring Cloud Contract WireMock in a Gradle based project, add the following dependency to your project:

testImplementation 'org.springframework.cloud:spring-cloud-contract-wiremock:${version}'

4. Using in application.yaml files

If you configure your test application.yaml file like this:

sample:
  port: ${wiremock.server.port}

And define the following beans:

@Component
@ConfigurationProperties(prefix = "sample")
@Data
public class PortProperties {
    private Integer port;
}

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PortService {
    private final PortProperties config;

    public Integer getPort() {
        return config.getPort();
    }
}

You can verify that sample.port is set to the randomly chosen wiremock port:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
public class PortServiceTest {
    @Autowired
    private Environment environment;

    @Autowired
    private PortService portService;

    @Test
    public void shouldReturnWireMockPort() {
        assertThat(portService.getPort())
                .isNotNull()
                .isEqualTo(Integer.parseInt(environment.getProperty("wiremock.server.port")));
    }
}