如何通过 WireMock 代理 Google API 客户端请求,以便能够记录和播放 API 响应以进行单元测试
我有一个类 GoogleApiClientWrapper
,它基本上处理与 Google 的交互,以进行身份验证并使用 Google 云端硬盘 Java SDK 版本:v3-rev110-1.23.0。
我正在使用以下依赖项:
google-api-client:1.28.0
google-http-client:1.28.0
google-http-client-apache- 2.0.0.jar
com.github.tomakehurst:wiremock-jre8:2.32.0
我正在尝试对我的类进行单元测试。所以我考虑使用 WireMock Record & 。回放功能可通过 WireMock 路由请求来记录对 Google API 的请求,以便能够记录给定请求的响应。
所以想法是创建 HttpTransport 配置为代理端口 8443 上的本地主机的所有请求,该端口是 WireMock 运行的端口,并将此 HttpTransport 注入到GoogleRefreshTokenRequest
构造函数或 Drive.Builder。然后 WireMock 配置为将本地主机上的请求代理到 google api url。因此,最终请求将第一次发送到 google api,然后在我能够记录响应之后,WireMock 将能够从保存的映射进行响应。
这里,GoogleApiClientWrapper
中 GoogleRefreshTokenRequest
的实现如下:
GoogleTokenResponse getGoogleTokenResponse(HttpTransport httpTransport,
JsonFactory jsonFactory,
String refreshToken,
String clientId,
String clientSecret,
List<String> exportScopes) throws IOException {
return new GoogleRefreshTokenRequest(httpTransport, jsonFactory, refreshToken, clientId, clientSecret)
.setScopes(exportScopes)
.execute();
}
这是带有 WireMock 代码的测试类,用于代理请求并记录映射。
public class GoogleApiWrapperTest {
@ClassRule
public static WireMockClassRule wireMockRule = new WireMockClassRule(WireMockConfiguration.wireMockConfig().httpsPort(8443));
@Test
public void testGetGoogleTokenResponse() throws IOException, GeneralSecurityException {
wireMockRule.startRecording("https://oauth2.googleapis.com/token");
GoogleApiClientWrapper clientWrapper= new GoogleApiClientWrapper();
HttpHost proxy = new HttpHost("127.0.0.1", 8443);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
HttpClient client = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
HttpTransport httpTransport = new ApacheHttpTransport(client);
String clientId = "my-client-id";
String clientSecret = "my-client-secret";
String tokenString = "sometoken";
String refreshToken = tokenString.split("\\|")[0];
GoogleTokenResponse actual = clientWrapper.getGoogleTokenResponse(httpTransport,JacksonFactory.getDefaultInstance(),refreshToken,clientId,clientSecret,Arrays.asList(DriveScopes.DRIVE_READONLY));
wireMockRule.stopRecording().getStubMappings();
}
}
创建映射后,以下代码将从测试类中删除:
wireMockRule.startRecording("https://oauth2.googleapis.com/token");
wireMockRule.stopRecording().getStubMappings();
当我运行它时,出现以下异常:
org.apache.http.client.ClientProtocolException
原因:org.apache.http.ProtocolException:服务器无法响应有效的 HTTP 响应
我还尝试基于此 answer
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.0", 8443));
HttpTransport httpTransport = new NetHttpTransport.Builder().setProxy(proxy).build();
如何解决此问题,或者 HttpTransport
或WireMockClassRule?或者有没有更简单的方法可以通过 WireMock 存储 google api 响应?
在测试使用 GoogleApiClientWrapper
的其他类时,我已经使用 Mockito 来模拟响应类,但在这个单元测试中我想尝试测试行为。
I have a class GoogleApiClientWrapper
which basically handles interactions with Google for authentication and listing files and drives using Google Drive Java SDK version: v3-rev110-1.23.0.
I am using the following dependencies:
google-api-client:1.28.0
google-http-client:1.28.0
google-http-client-apache-2.0.0.jar
com.github.tomakehurst:wiremock-jre8:2.32.0
I am trying to unit test my class. So I thought about using WireMock Record & Playback feature to record the requests to Google APIs by routing the requests via WireMock to be able to record the responses for a given request.
So the idea is to create an instance of HttpTransport which is configured to proxy all requests to localhost on port 8443 which is the port WireMock is running on and inject this HttpTransport
to the GoogleRefreshTokenRequest
constructor or the Drive.Builder. Then WireMock is configured to proxy requests on localhost to the google api url. So ultimately the requests will be sent to google api the first time then after I am able to record the responses WireMock will be able to respond from the saved mappings.
Here it the implementation of GoogleRefreshTokenRequest
in GoogleApiClientWrapper
is as follows:
GoogleTokenResponse getGoogleTokenResponse(HttpTransport httpTransport,
JsonFactory jsonFactory,
String refreshToken,
String clientId,
String clientSecret,
List<String> exportScopes) throws IOException {
return new GoogleRefreshTokenRequest(httpTransport, jsonFactory, refreshToken, clientId, clientSecret)
.setScopes(exportScopes)
.execute();
}
Here is the test class with WireMock code to proxy the request and record the mappings.
public class GoogleApiWrapperTest {
@ClassRule
public static WireMockClassRule wireMockRule = new WireMockClassRule(WireMockConfiguration.wireMockConfig().httpsPort(8443));
@Test
public void testGetGoogleTokenResponse() throws IOException, GeneralSecurityException {
wireMockRule.startRecording("https://oauth2.googleapis.com/token");
GoogleApiClientWrapper clientWrapper= new GoogleApiClientWrapper();
HttpHost proxy = new HttpHost("127.0.0.1", 8443);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
HttpClient client = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
HttpTransport httpTransport = new ApacheHttpTransport(client);
String clientId = "my-client-id";
String clientSecret = "my-client-secret";
String tokenString = "sometoken";
String refreshToken = tokenString.split("\\|")[0];
GoogleTokenResponse actual = clientWrapper.getGoogleTokenResponse(httpTransport,JacksonFactory.getDefaultInstance(),refreshToken,clientId,clientSecret,Arrays.asList(DriveScopes.DRIVE_READONLY));
wireMockRule.stopRecording().getStubMappings();
}
}
The following code will be removed from the test class once mapping created:
wireMockRule.startRecording("https://oauth2.googleapis.com/token");
wireMockRule.stopRecording().getStubMappings();
When I run it I get the following exception:
org.apache.http.client.ClientProtocolException
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
I also tried to create the HttpTransport as follows based on this answer
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.0", 8443));
HttpTransport httpTransport = new NetHttpTransport.Builder().setProxy(proxy).build();
How to solve this issue or is there a missing configuration for the HttpTransport
or for the WireMockClassRule? Or is there an easier way to be able to store the google api responses via WireMock?
I already used Mockito to mock the responses when testing other classes that use the GoogleApiClientWrapper
class but in this unit test I want to try to test the behaviour.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论