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

如何在测试中Stub Google OAuth令牌刷新的响应?

解决Google API令牌刷新请求Stub问题

问题背景

使用com.google.api.services.gmail.Gmail发送邮件时,测试触发sendEmail(Message message)方法,因用户令牌过期,.execute()会发起令牌刷新请求POST https://oauth2.googleapis.com/token。由于该URL在Google API库中硬编码,无法通过替换域名的方式用WireMock Stub响应,需其他可行方案。

可行方案

方案1:使用Google API Client官方Mock HTTP传输

Google API Client库自带MockHttpTransport,可直接拦截并模拟所有HTTP请求,包括令牌刷新请求。

步骤:

  1. 创建MockHttpTransport实例,自定义请求处理逻辑,匹配POST https://oauth2.googleapis.com/token请求并返回模拟的令牌响应。
  2. 将该MockHttpTransport配置到Gmail客户端的初始化流程中。

代码示例:

// 构建Mock HTTP传输,处理令牌刷新请求
MockHttpTransport mockTransport = new MockHttpTransport() {
    @Override
    public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
        if ("POST".equals(method) && url.equals("https://oauth2.googleapis.com/token")) {
            return new MockLowLevelHttpRequest() {
                @Override
                public LowLevelHttpResponse execute() throws IOException {
                    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
                    response.setStatusCode(200);
                    response.setContentType("application/json");
                    // 返回模拟的刷新令牌响应
                    response.setContent("{\"access_token\":\"new-mock-token\",\"expires_in\":3600}");
                    return response;
                }
            };
        }
        // 其他请求可根据需要处理,或抛出异常
        throw new IOException("Unexpected request: " + method + " " + url);
    }
};

// 初始化Gmail客户端时使用Mock传输
Gmail gmail = new Gmail.Builder(mockTransport, JacksonFactory.getDefaultInstance(), credential)
        .setApplicationName("Your-App-Name")
        .build();

方案2:通过JVM系统代理拦截请求到WireMock

即使URL硬编码,也可通过设置JVM系统代理,将所有HTTPS请求转发到WireMock服务,由WireMock处理令牌刷新请求。

步骤:

  1. 启动WireMock服务,配置对POST /token请求的Stub响应。
  2. 在测试代码启动前设置JVM系统代理:
System.setProperty("https.proxyHost", "localhost");
System.setProperty("https.proxyPort", "8080"); // WireMock监听端口
  1. 注意:需处理WireMock的HTTPS证书问题,可生成自签名证书并配置JVM信任,或让WireMock使用HTTP模式(仅测试环境可用)。

方案3:使用Mockito Spy替换HTTP请求逻辑

通过Mockito Spy替换Google API库中HttpTransport的实现,拦截令牌刷新请求并返回模拟响应。

代码示例:

// 获取真实的HttpTransport实例
HttpTransport realTransport = Gmail.DEFAULT_TRANSPORT;
// Spy该实例,拦截buildRequest方法
HttpTransport spyTransport = Mockito.spy(realTransport);

Mockito.when(spyTransport.buildRequest(Mockito.eq("POST"), Mockito.eq("https://oauth2.googleapis.com/token")))
        .thenAnswer(invocation -> {
            MockLowLevelHttpRequest mockRequest = new MockLowLevelHttpRequest();
            mockRequest.setResponse(new MockLowLevelHttpResponse() {{
                setStatusCode(200);
                setContentType("application/json");
                setContent("{\"access_token\":\"mock-refreshed-token\",\"expires_in\":3600}");
            }});
            return mockRequest;
        });

// 使用Spy后的传输初始化Gmail客户端
Gmail gmail = new Gmail.Builder(spyTransport, JacksonFactory.getDefaultInstance(), credential)
        .setApplicationName("Your-App-Name")
        .build();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:52:37