Spring Boot 在pact-jvm中为多个提供者设置模拟端口

sd2nnvve  于 2023-03-08  发布在  Spring
关注(0)|答案(1)|浏览(144)

我试图通过重写一些wirerock测试来学习pact框架,这些测试是用来测试用java和springboot编写的应用程序的,我提供了一个简化的例子来说明我们最终陷入的困境:
Consumertest.java

@ExtendWith(PactConsumerTestExt.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class ContractConsumerTests {

    @Autowired
    private MockMvc mockMvc;

    @Pact(provider = "provider1", consumer = "my_consumer")
    public V4Pact provider1Pact(PactBuilder builder) {
        ...
    }

    @Pact(provider = "provider2", consumer = "my_consumer")
    public V4Pact provider2Pact(PactBuilder builder) {
        ...
    }

    @Test
    @PactTestFor(pactMethods = {"provider1Pact", "provider2Pact"})
    public void testMultipleProvider(@ForProvider("provider1") MockServer provider1Mock, @ForProvider("provider2") MockServer provider2Mock) throws Exception {
        System.out.println(provider1Mock.getPort()); //random port != 1000
        System.out.println(provider2Mock.getPort()); //random port != 2000

        //Calling this controller requires fetching data from provider1 and provider2 to compute the result
        //application is configured to go to provider1 on localhost:1000 and provider 2 on localhost:2000
        mockMvc.perform(get("/my/url")
                        .param("foo", "abc")
                        .param("bar", "123"))
                .andExpect(status().isOk())
                .andExpect(content().string("expectedcontent"));
    }
}

Application.yml

application:
  client:
    provider1:
      url: http://localhost:1000/
    provider2:
      url: http://localhost:2000/

以前我们会有一个单一的wirerock示例运行在一个设置端口(1000)上,并且应用程序配置会为两个提供者指向该端口。但是现在我们不能这样做,因为产生的合约将包含两个提供者的请求。如果我们将合约给provider1,它将无法满足provider2的请求,反之亦然。
两年前也有人问过类似的问题:How to define multiple providers using @PactTestFor,答案是分割测试。由于各种原因,这可能对我们不起作用。但更重要的是,现在支持多提供程序测试:https://docs.pact.io/implementation_guides/jvm/consumer/junit5#using-multiple-providers-in-a-test-425
现在,当您的测试中只有一个提供者时,您可以使用以下命令指定模拟的端口:

@PactTestFor(providerName = "provider1", port="1000")

这将匹配应用程序中配置的端口,一切正常。但是,由于我们使用多个提供程序,使用“port=1000 "将导致”address already in use“异常。当两个mockserver都尝试在端口1000上启动时,这是有意义的。
忽略端口将默认为一个随机端口,这将解决异常,但应用程序被配置为调用一个静态端口,这将永远不会匹配随机端口,因此总是失败。
这就引出了以下问题:
如何使用在应用程序配置中选择的任意随机模拟端口?

我们如何设置每个MockServer示例的端口以匹配我们配置中的端口?

相关问题