【问题标题】:How to mock Google API AndroidPublisher request如何模拟 Google API AndroidPublisher 请求
【发布时间】:2017-03-08 02:59:03
【问题描述】:

我有一个类向 AndroidPublisher API 发出请求以获取 Purchases.Subscriptions.get 资源。如何使用 com.google.api.client.testing 包中的类模拟 OAuth 请求和调用以获取订阅资源?

获取订阅的代码如下:

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());

这是我目前尝试模拟 JSON 响应但未成功的方式:

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();

当我使用模拟类运行测试时,我得到以下堆栈跟踪:

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)

我错过了什么?如何模拟 OAuth2 响应以及获取订阅的调用?

【问题讨论】:

标签: java android google-api-client google-api-java-client


【解决方案1】:

我能够找出我的问题。除了模拟 HttpTransport,我还必须提供一个模拟 GoogleCredential,例如:

new MockGoogleCredential.Builder().build();

【讨论】:

【解决方案2】:

@Sukhmeet Singh 我不确定您的部署环境是什么样的,但我们使用的是 Spring Boot。我在@Configuration 文件中声明了以下 Spring bean。

@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();
}

然后在我的集成测试中,特别是我们使用 cucumber-jvm,我有另一个特定于测试的 @Configuration 文件,它使用 spring 注释 @Primary 覆盖这些 bean。

@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;
}

现在我有一些其他类可以帮助我模拟不同场景的多个响应,但这应该会给你足够的想法来弄清楚。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2020-06-19
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多