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
相关产品推荐
相关产品推荐

