Set property using random port for wired device in spring boot test

I have a Spring boot test that uses wiremock to mock an external service. To avoid conflicts with parallel assemblies, I do not want to set a fixed port number for wiremock and would like to rely on its dynamic port configuration.

The application uses the ( external.baseUrl) property set in application.yml (in the src / test / resources section). However, I did not find a way to programmatically override this. I tried something like this:

    WireMockServer wireMockServer = new WireMockServer();
    wireMockServer.start();
    WireMock mockClient = new WireMock("localhost", wireMockServer.port());
    System.setProperty("external.baseUrl", "http://localhost:" + wireMockServer.port());

but this did not work, and the value in application.yml was used instead. All other solutions that I looked at override the property with a static value (for example, in some annotation), but I do not know the value of the wiremock port before running the test.

Clarification:

Both Spring boot and wiremock work on random ports. This is great, and I know how to get the cost of both ports. However, wiremock has to make fun of an external service, and I need to tell my application how to achieve it. I am doing this with a property external.baseUrl. The value that I want to set in my test, of course, depends on the port number for the wired module. My problem is how to set the property programmatically in the Spring boot test .

+6
7

Spring Cloud Contract Wiremock

JUnit, ${wiremock.port} /yaml

WireMockRestServiceServer WireMock RestTemplate RestTemplate URL- .

+3

Spring Boot, beans.

@TestConfiguration beans :

private static WireMockServer wireMockServer1 = getWireMockServer();
private static WireMockServer wireMockServer2 = getWireMockServer();
private static WireMockServer wireMockServer3 = getWireMockServer();

private static WireMockServer getWireMockServer() {
    final WireMockServer wireMockServer = new WireMockServer(options().dynamicPort());
    wireMockServer.start();
    return wireMockServer;
}

@TestConfiguration
static class TestConfig {
    @Bean
    @Primary
    public BeanUsingAProperty1 getBean1() {
        BeanUsingAProperty myBean = new BeanUsingAProperty();
        myBean.setPort(wireMockServer.port());
        return myBean;
    }

    @Bean
    @Primary
    public BeanUsingAProperty2 getBean2() {
        String baseUrl = "http://localhost:" + wireMockServer2.port();
        return new BeanUsingAProperty2(baseUrl);
    }

    @Bean
    @Primary
    public BeanUsingAProperty3 getBean3() {
        String baseUrl = "http://localhost:" + wireMockServer3.port() + "/request";
        return new BeanUsingAProperty3(new RestTemplate(), baseUrl, "someOtherParameter");
    }
}

BeanUsingAProperty , , Wiremock.

, ,

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {
    MySpringBootApplication.class, MyIntegrationTest.TestConfig.class })

, API Wiremock, , . , beans , .

+5

application.properties:

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

, wiremock.server.port wiremock.server.port SpringBootTest, , @AutoConfigureWireMock .

+2

:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
class YourTestClass {
    @LocalServerPort
    int port;

    public void test() {
        WireMockServer wireMockServer = new WireMockServer(port);
        wireMockServer.start();
        WireMock mockClient = new WireMock("localhost", port);
    }
}
0

, Spring Boot, String[] . , , YML .

:

String[] args = new String[]{"--my.prop=foo"};
SpringApplication.run(Application.class, args);

API, Spring Boot ( ) .

, wiremock, . : PaymentServiceContractTest.java

P.S. ( , ) WireMock, ;)

0

, fooobar.com/questions/1693419/... (. wiremock.port), , , Spring Cloud Contract 2.1.2.RELEASE.

1.

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. WireMock

wiremock.server.port, @AutoConfigureWireMock :

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

3. Gradle

Spring Cloud Contract WireMock Gradle, :

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

4. application.yaml

application.yaml :

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

:

@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();
    }
}

, sample.port wiremock:

@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")));
    }
}
0

How do you read external.baseUrl? If you use the annotated property @Value, you can use ReflectionTestUtilsto set the port after setting up the mock server.

ReflectionTestUtils.setField(yourTestClass, "youPort",  wireMockServer.port());
-1
source

Source: https://habr.com/ru/post/1693419/


All Articles