You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit测试中如何获取Pact Mock Server动态端口以配置OpenFeign?

解决Pact Mock Server端口提前配置给Spring Feign客户端的问题

方法1:用@DynamicPropertySource动态注入属性

这是最直接的Spring Boot原生方案,能在应用上下文初始化阶段动态把Pact Mock Server的端口注入到环境变量里,刚好满足Feign客户端的配置需求。

示例代码:

import au.com.dius.pact.provider.junit5.PactVerificationContext;
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
import au.com.dius.pact.provider.spring.junit5.MockServerConfig;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;

@SpringBootTest
@ExtendWith(PactVerificationInvocationContextProvider.class)
@MockServerConfig(host = "localhost", port = 0) // 0表示随机分配端口
public class FeignClientPactTest {

    @DynamicPropertySource
    static void configureFeignProperties(DynamicPropertyRegistry registry) {
        // 将MockServer端口注入到Feign客户端的配置属性中
        registry.add("feign.client.config.your-client.url", 
            () -> "http://localhost:" + PactVerificationContext.getMockServer().getPort());
    }

    @TestTemplate
    void pactVerificationTestTemplate(PactVerificationContext context) {
        context.verifyInteraction();
    }
}

注意替换your-client为你实际的Feign客户端名称,若需全局配置Feign,可改用feign.client.default.url属性。

方法2:自定义TestExecutionListener提前初始化MockServer

如果需要在上下文加载前就拿到端口,可以自定义监听器提前启动MockServer,并将端口存入系统属性:

import au.com.dius.pact.core.model.MockServer;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.AbstractTestExecutionListener;

public class PactPortPreloadListener extends AbstractTestExecutionListener {

    @Override
    public void beforeTestClass(TestContext testContext) throws Exception {
        // 提前启动MockServer
        MockServer mockServer = MockServer.createDefault();
        // 将端口存入系统属性
        System.setProperty("pact.mockserver.port", String.valueOf(mockServer.getPort()));
        // 把MockServer实例存入上下文,方便后续复用
        testContext.getApplicationContext().getBeanFactory().registerSingleton("pactMockServer", mockServer);
    }

    @Override
    public void afterTestClass(TestContext testContext) throws Exception {
        // 测试结束后关闭MockServer
        MockServer mockServer = testContext.getApplicationContext().getBean(MockServer.class);
        mockServer.stop();
    }
}

在测试类上引入这个自定义监听器:

@SpringBootTest
@TestExecutionListeners(listeners = {PactPortPreloadListener.class, SpringBootTestExecutionListener.class})
public class FeignClientPactTest {
    // 测试逻辑代码
}

之后就能在application-test.yml里直接引用该属性:

feign:
  client:
    config:
      your-client:
        url: http://localhost:${pact.mockserver.port}

注意事项

  • 确保Pact Spring依赖版本在v4.x及以上,以支持@MockServerConfig和PactVerificationContext的静态获取方法。
  • 使用port=0配置随机端口,可避免端口冲突问题。

内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:35:23