问题
I've got a class that makes a request to the AndroidPublisher API to get the Purchases.Subscriptions.get resource. How does one mock out the OAuth request and call to get the subscription resource using the classes from the package com.google.api.client.testing?
Here is the code to get the subscription:
HttpTransport httpTransport = new NetHttpTransport.Builder().build();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("email")
.setServiceAccountScopes(singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
.setServiceAccountPrivateKeyFromP12File(new File("file.p12"))
.build();
AndroidPublisher androidPublisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("appname")
.build();
AndroidPublisher.Purchases.Subscriptions.Get get = androidPublisher.purchases().subscriptions().get(
"appname",
"productId",
"purchaseToken");
SubscriptionPurchase subscription = get.execute();
System.out.println(subscription.toPrettyString());
Here is how I am currently, but unsuccessfully, trying to mock out the JSON responses:
MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse();
mockResponse.setStatusCode(200);
mockResponse.setContentType(Json.MEDIA_TYPE);
mockResponse.setContent("{\n" +
" \"autoRenewing\" : true,\n" +
" \"countryCode\" : \"US\",\n" +
" \"developerPayload\" : \"\",\n" +
" \"expiryTimeMillis\" : \"1480019001357\",\n" +
" \"kind\" : \"androidpublisher#subscriptionPurchase\",\n" +
" \"paymentState\" : 1,\n" +
" \"priceAmountMicros\" : \"990000\",\n" +
" \"priceCurrencyCode\" : \"USD\",\n" +
" \"startTimeMillis\" : \"1477333413210\"\n" +
"}");
return new MockHttpTransport.Builder().setLowLevelHttpResponse(mockResponse).build();
When I run the test with the mock classes I get the following stacktrace:
java.lang.IllegalArgumentException: no JSON input found
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:125)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:49)
at com.google.api.client.json.JsonParser.startParsing(JsonParser.java:223)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:380)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
What am I missing? How does one mock out the OAuth2 response as well as the call to get the subscription?
回答1:
I was able to figure out my issue. In addition to mocking out the HttpTransport I also had to provide a mock GoogleCredential like:
new MockGoogleCredential.Builder().build();
回答2:
@Sukhmeet Singh I'm not sure what your deployment environment is like but we are using Spring Boot. I have the following spring beans declared in a @Configuration
file.
@Bean
public HttpTransport httpTransport() {
return new NetHttpTransport.Builder().build();
}
@Bean
public JsonFactory jsonFactory() {
return JacksonFactory.getDefaultInstance();
}
@Bean
public GoogleCredential googleCredential(
final HttpTransport httpTransport,
final JsonFactory jsonFactory) {
final String serviceAccountUserName = env.getRequiredProperty("<redacted>");
final String serviceAccountPrivateKeyFile = env.getRequiredProperty("<redacted>");
try {
return new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountUserName)
.setServiceAccountScopes(singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
.setServiceAccountPrivateKeyFromP12File(new File(serviceAccountPrivateKeyFile))
.build();
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
@Bean
public AndroidPublisher androidPublisher(
final GoogleAppPackageName googleAppPackageName,
final HttpTransport httpTransport,
final JsonFactory jsonFactory,
final GoogleCredential googleCredential) {
return new AndroidPublisher.Builder(httpTransport, jsonFactory, googleCredential)
.setApplicationName(googleAppPackageName.getValue())
.build();
}
Then in my integration tests, specifically we are using cucumber-jvm, I have another test specific @Configuration
file that overrides those beans using the spring annotation @Primary
.
@Primary
@Bean
public GoogleCredential googleCredential() {
return new MockGoogleCredential.Builder().build();
}
@Primary
@Bean
public HttpTransport httpTransport() {
final MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse();
mockResponse.setStatusCode(200);
mockResponse.setContentType(Json.MEDIA_TYPE);
mockResponse.setContent("<desired JSON response>");
final MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url);
request.setResponse(mockResponse);
return request;
}
Now I have some other classes that I use to help me mock out multiple responses for different scenario's but this should give you enough of an idea to figure it out.
Hope it helps.
来源:https://stackoverflow.com/questions/40250497/how-to-mock-google-api-androidpublisher-request