在spring boot test中使用wiremock随机端口设置属性

Nic*_*tti 7 java configuration spring-boot wiremock spring-boot-test

我有一个Spring Boot测试,它使用wiremock来模拟外部服务.为了避免与并行构建冲突,我不想为wiremock设置固定端口号,并且希望依赖其动态端口配置.

该应用程序使用application.yml中external.baseUrl设置的property()(在src/test/resources下).但是我找不到以编程方式覆盖它的方法.我尝试过这样的事情:

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

但它不起作用,而是使用application.yml中的值.我看过的所有其他解决方案都使用静态值覆盖属性(例如在某些注释中),但在运行测试之前我不知道wiremock端口的值.

澄清:

弹簧引导和线缆都在随机端口上运行.那很好,我知道如何获得两个端口的价值.然而,wiremock应该模拟外部服务,我需要告诉我的应用程序如何到达它.我和这家external.baseUrl酒店一起做.我想在测试中设置的值当然取决于线程端口号.我的问题是如何在Spring启动测试中以编程方式设置属性.

use*_*637 10

在 application.properties 中使用属性替换:

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

这需要wiremock.server.port在 SpringBootTest 初始化之前设置该属性,这可以通过@AutoConfigureWireMock在测试类中添加注释来实现。

  • 如果“wiremock.server.port”仅在运行时定义,则这将不起作用。 (3认同)

Dag*_*gon 7

考虑使用Spring Cloud Contract Wiremock

已经有一个 JUnit 规则构建器,它允许指定${wiremock.port}在属性/yaml 文件中设置随机端口

或者您可以使用WireMockRestServiceServer将 WireMock 绑定到您的,RestTemplate这样您甚至不需要在测试中覆盖 URL。


Nic*_*tti 5

我找不到在Spring Boot集成测试中覆盖属性的方法,因为测试仅在创建应用程序并且已经配置了所有bean之后运行.

作为一种解决方法,我@TestConfiguration在测试中添加了一个替换应用程序中的bean:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效地替换了BeanUsingAProperty测试中定义的那个,以便它具有Wiremock的正确端口号.

要获取此配置,我必须在测试注释中添加此类

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {
    MySpringBootApplication.class, MyIntegrationTest.TestConfig.class })
Run Code Online (Sandbox Code Playgroud)

请注意,我使用非静态Wiremock API,因为我有几个这样的外部服务,每个都需要被模拟.请注意,根据每个bean的设计方式,如何构建不同的bean.


Lam*_*bda 5

/sf/answers/3420168741/(即wiremock.port)中提到的属性名称不正确,至少从 Spring Cloud Contract version 开始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+");
    }

}
Run Code Online (Sandbox Code Playgroud)

2. 其他 WireMock 属性

除了wiremock.server.port, 还@AutoConfigureWireMock用其他一些属性填充环境:

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

3. Gradle 依赖

要在基于 Gradle 的项目中使用 Spring Cloud Contract WireMock,请将以下依赖项添加到您的项目中:

testImplementation 'org.springframework.cloud:spring-cloud-contract-wiremock:${version}'
Run Code Online (Sandbox Code Playgroud)

4. 在application.yaml文件中使用

如果您application.yaml像这样配置测试文件:

sample:
  port: ${wiremock.server.port}
Run Code Online (Sandbox Code Playgroud)

并定义以下bean:

testImplementation 'org.springframework.cloud:spring-cloud-contract-wiremock:${version}'
Run Code Online (Sandbox Code Playgroud)

您可以验证sample.port是否设置为随机选择的wiremock 端口:

sample:
  port: ${wiremock.server.port}
Run Code Online (Sandbox Code Playgroud)