使用Pact的HttpsTestTarget时如何传递认证Header?
在Quarkus+Pact的Provider验证测试中为HttpsTestTarget添加认证Token
我用Java、Pact搭配Quarkus扩展(io.quarkiverse.pact:quarkus-pact-provider和io.quarkiverse.pact:quarkus-pact-consumer)做契约验证测试,当前用HttpsTestTarget指定测试目标,但我的服务调用需要携带认证Token(类似下面的cURL请求),请问该怎么实现?
参考cURL请求
curl --location 'https://gateway.production.xpto.io/xpto/v2/xpto?attribute=%23xpto_client' \ --header 'Authorization: Bearer 3rdcD=V8KoW!eJaPjWx04lhuVUqXFyr2Bz-HjANr7Fy9eUzOW!7JJXeVwPe6NTSAlPxxn4C!qXzsqz!UzSrj/gH2o-BL=S?IsbMrb/zG00pjOWm7U=08PYz5UPko1JttfuI!v6rRH4P8fsJ-M6E0kR0Ds7tsqbRbjGGt8NsdzO4VPG1/U3uIYZ7IG/yWG8-1tUyq8V4DPmwtmxM/5CieFaPHhUJyRyjR!24K-7m4FGNd??gCr!t57JTvW2vrjEpj'
当前验证测试代码
package com.company.pact.provider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; import au.com.dius.pact.provider.junit5.HttpsTestTarget; import au.com.dius.pact.provider.junit5.PactVerificationContext; import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider; import au.com.dius.pact.provider.junitsupport.Provider; import au.com.dius.pact.provider.junitsupport.State; import au.com.dius.pact.provider.junitsupport.loader.PactBroker; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @Provider("XPTOProvider") @PactBroker(host = "localhost", port = "9292") public class XPTOProviderContractTest { @BeforeEach void beforeEach(PactVerificationContext context) { context.setTarget(new HttpsTestTarget("gateway.production.xpto.io", 443, "/xpto/v2/xpto?attribute=%23xpto_client")); } @TestTemplate @ExtendWith(PactVerificationInvocationContextProvider.class) void pactVerificationTestTemplate(PactVerificationContext context) { context.verifyInteraction(); } @State("test GET") public void testGet() { System.out.println("test GET"); } }
解决方案
方式1:自定义TestTarget添加全局认证头
HttpsTestTarget本身不支持直接设置请求头,可通过继承它并扩展请求头处理逻辑实现:
package com.company.pact.provider; import au.com.dius.pact.provider.junit5.HttpsTestTarget; import org.apache.http.client.methods.HttpRequestBase; public class AuthenticatedHttpsTestTarget extends HttpsTestTarget { private final String authToken; public AuthenticatedHttpsTestTarget(String host, int port, String path, String authToken) { super(host, port, path); this.authToken = authToken; } @Override public void applyRequestHeaders(HttpRequestBase request) { super.applyRequestHeaders(request); // 注入Authorization头 request.addHeader("Authorization", "Bearer " + authToken); } }
修改测试类的beforeEach方法,使用自定义目标:
@BeforeEach void beforeEach(PactVerificationContext context) { // 建议从环境变量/Quarkus配置读取Token,避免硬编码 String authToken = "你的认证Token"; context.setTarget(new AuthenticatedHttpsTestTarget("gateway.production.xpto.io", 443, "/xpto/v2/xpto?attribute=%23xpto_client", authToken)); }
方式2:使用Pact请求过滤器动态注入头
直接在测试模板方法中添加全局请求过滤器,为所有验证请求注入认证头:
@TestTemplate @ExtendWith(PactVerificationInvocationContextProvider.class) void pactVerificationTestTemplate(PactVerificationContext context) { // 添加请求过滤器 context.addRequestFilter((request, contextMap) -> { request.addHeader("Authorization", "Bearer 你的认证Token"); }); context.verifyInteraction(); }
注意事项
- 禁止硬编码Token:优先从Quarkus配置(
application-test.properties)、环境变量或测试资源文件读取,例如通过@ConfigProperty注入:@ConfigProperty(name = "test.auth.token") String authToken; - 多状态适配:如果不同
@State需要不同Token,可在@State方法中动态调整请求头,或在过滤器中根据当前状态判断注入。
内容的提问来源于stack exchange,提问作者Railane Passos
相关产品推荐
相关产品推荐

