How can I make WireMock port more dynamic to use it for testing service

niemar picture niemar · Mar 20, 2018 · Viewed 9.9k times · Source

I am using wiremock to mock github api to do some testing of my service. The service calls github api. For the tests I am setting endpoint property to

github.api.endpoint=http://localhost:8087

This host and port are the same as wiremock server @AutoConfigureWireMock(port = 8087) so I can test different scenarios like : malformed response, timeouts etc.

How can I make this port dynamic to avoid case when it is already used by system ? Is there a way to get wiremock port in tests and reassign endpoint property ?

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 8087)
@TestPropertySource(properties ={"github.api.endpoint=http://localhost:8087"}) 
public class GithubRepositoryServiceTestWithWireMockServer {

@Value("${github.api.client.timeout.milis}")
private int githubClientTimeout;

@Autowired
private GithubRepositoryService service;

@Test
public void getRepositoryDetails() {
    GithubRepositoryDetails expected = new GithubRepositoryDetails("niemar/xf-test", null,
            "https://github.com/niemar/xf-test.git", 1, "2016-06-12T18:46:24Z");
    stubFor(get(urlEqualTo("/repos/niemar/xf-test"))
            .willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("/okResponse.json")));

    GithubRepositoryDetails repositoryDetails = service.getRepositoryDetails("niemar", "xf-test");

    Assert.assertEquals(expected, repositoryDetails);
}

@Test
public void testTimeout() {
    GithubRepositoryDetails expected = new GithubRepositoryDetails("niemar/xf-test", null,
            "https://github.com/niemar/xf-test.git", 1, "2016-06-12T18:46:24Z");
    stubFor(get(urlEqualTo("/repos/niemar/xf-test"))
            .willReturn(aResponse()
                    .withHeader("Content-Type", "application/json")
                    .withBodyFile("/okResponse.json")
                    .withFixedDelay(githubClientTimeout * 3)));

    boolean wasExceptionThrown = false;
    try {
        GithubRepositoryDetails repositoryDetails = service.getRepositoryDetails("niemar", "xf-test");
    } catch (GithubRepositoryNotFound e) {
        wasExceptionThrown = true;
    }

    Assert.assertTrue(wasExceptionThrown);
}

Answer

Stefan Birkner picture Stefan Birkner · Apr 26, 2019

You have to set the WireMock port to 0 so that it chooses a random port and then use a reference to this port (wiremock.server.port) as part of the endpoint property.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
@TestPropertySource(properties = {
    "github.api.endpoint=http://localhost:${wiremock.server.port}"
}) 
public class GithubRepositoryServiceTestWithWireMockServer {
    ....
}

See also Spring Cloud Contract WireMock.