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

Resteasy集成测试中WireMock未捕获Trustpilot API请求问题排查

问题根源分析

你遇到的核心问题是:你的MyResource仍然在向真实的Trustpilot API发送请求,而非WireMock的模拟服务,所以WireMock自然捕获不到请求记录。虽然你启动了WireMock并配置了动态端口,但代码里硬编码的Trustpilot API域名并没有指向WireMock运行的localhost地址。

修复步骤

1. 让Trustpilot API URL可配置

首先要修改MyResource,把硬编码的第三方API地址改成可注入的配置项,这样测试时能替换成WireMock的地址。

修改MyResource代码:

import javax.inject.Inject;
import javax.inject.Named;

public class MyResource {
    // 替换硬编码URL为可注入的配置
    @Inject
    @Named("trustpilotApiBaseUrl")
    private String trustpilotApiBaseUrl;

    // 构建请求时使用这个可配置的base URL
    private URI buildTrustpilotRequestUri(String businessUnitId) {
        return UriBuilder.fromUri(trustpilotApiBaseUrl)
                .path("/v1/private/product-reviews/business-units/{businessUnitId}/invitation-links")
                .build(businessUnitId);
    }
}

然后在测试配置类MyResourceTestContext中,注入WireMock的运行地址:

import com.github.tomakehurst.wiremock.WireMockRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyResourceTestContext {
    @Bean
    @Named("trustpilotApiBaseUrl")
    public String trustpilotApiBaseUrl(WireMockRule wireMockRule) {
        // 应用用HTTPS调用就用httpsPort(),HTTP则用port()
        return "https://localhost:" + wireMockRule.httpsPort();
    }

    // 其他Bean配置...
}

2. 修正WireMock的Stub与验证逻辑

WireMock匹配请求时不需要完整域名和端口,只需要匹配相对路径即可(因为请求现在发往localhost的WireMock端口)。你之前用完整URI创建stub和验证,会导致匹配失败。

修改测试代码中的stub和验证部分:

// 改用相对路径匹配
String trustpilotRelativePath = "/v1/private/product-reviews/business-units/" + BUSINESS_UNIT_ID + "/invitation-links";

// 创建Stub
stubFor(post(urlEqualTo(trustpilotRelativePath))
        .willReturn(okJson("{\"reviewLinkId\":\"" + REVIEW_LINK_ID + "\"," + "\"reviewUrl\":\"" + expectedRedirectURI.toString() + "\"}")));

// 验证请求
WireMock.verify(1, postRequestedFor(urlEqualTo(trustpilotRelativePath)));

3. 处理HTTPS证书信任问题

WireMock默认使用自签名HTTPS证书,Resteasy客户端会拒绝连接。需要配置客户端忽略SSL证书验证:

在测试配置中添加忽略SSL的Resteasy客户端Bean:

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

@Bean
public ResteasyClient resteasyClient() throws Exception {
    // 创建信任所有证书的TrustManager
    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
    };

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, new SecureRandom());

    // 构建忽略SSL验证的客户端
    return new ResteasyClientBuilder()
            .sslContext(sslContext)
            .hostnameVerifier((hostname, session) -> true)
            .build();
}

4. 修复代码笔误

你构建apiRequestURI时,路径里多了一个闭合大括号:

.fromUri("https://api.trustpilot.com/v1/private/product-reviews/business-units"
        + "/{businessUnitId}}/invitation-links")

把{businessUnitId}}改成{businessUnitId},避免生成错误URL。

验证修复效果

完成以上修改后重新运行测试:

  • MyResource会向WireMock的HTTPS端口发送请求
  • WireMock会捕获请求并返回预设响应
  • 验证逻辑会匹配到相对路径的请求,不再抛出VerificationException

内容的提问来源于stack exchange,提问作者P.Raber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:57:28