如何在使用 Retrofit 2 进行单元测试期间创建 Retrofit.Response 对象

2024-02-14

在使用 RxJava 和 Retrofit 2 时,我尝试创建单元测试来覆盖我的应用程序何时收到特定响应。

我遇到的问题是,在 Retrofit 2 中,我看不到在不使用反射的情况下创建 Retrofit.Response 对象的好方法。

@Test
public void testLogin_throwsLoginBadRequestExceptionWhen403Error() {


    Request.Builder requestBuilder = new Request.Builder();
    requestBuilder.get();
    requestBuilder.url("http://localhost");

    Response.Builder responseBuilder = new Response.Builder();
    responseBuilder.code(403);
    responseBuilder.protocol(Protocol.HTTP_1_1);
    responseBuilder.body(ResponseBody.create(MediaType.parse("application/json"), "{\"key\":[\"somestuff\"]}"));
    responseBuilder.request(requestBuilder.build());

    retrofit.Response<LoginResponse> aResponse = null;

    try {
        Constructor<retrofit.Response> constructor= (Constructor<retrofit.Response>) retrofit.Response.class.getDeclaredConstructors()[0];
        constructor.setAccessible(true);
        aResponse = constructor.newInstance(responseBuilder.build(), null, null);
    } catch (Exception ex) {
        //reflection error
    }

    doReturn(Observable.just(aResponse)).when(mockLoginAPI).login(anyObject());

    TestSubscriber testSubscriber = new TestSubscriber();
    loginAPIService.login(loginRequest).subscribe(testSubscriber);

    Throwable resultError = (Throwable) testSubscriber.getOnErrorEvents().get(0);
    assertTrue(resultError instanceof LoginBadRequestException);
}

我尝试使用以下内容,但这会创建 OkHttp 响应与 Retrofit 响应。

    Request.Builder requestBuilder = new Request.Builder();
    requestBuilder.get();
    requestBuilder.url("http://localhost");

    Response.Builder responseBuilder = new Response.Builder();
    responseBuilder.code(403);
    responseBuilder.protocol(Protocol.HTTP_1_1);

The retrofit.Response https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit2/Response.java类有静态工厂方法来创建实例:

public static <T> Response<T> success(T body) {
  /* ... */
}

public static <T> Response<T> success(T body, com.squareup.okhttp.Response rawResponse) {
  /* ... */
}

public static <T> Response<T> error(int code, ResponseBody body) {
  /* ... */
}

public static <T> Response<T> error(ResponseBody body, com.squareup.okhttp.Response rawResponse) {
  /* ... */
}

例如:

Account account = ...;
retrofit.Response<Account> aResponse = retrofit.Response.success(account);

Or:

retrofit.Response<Account> aResponse = retrofit.Response.error(
  403, 
  ResponseBody.create(
    MediaType.parse("application/json"),
    "{\"key\":[\"somestuff\"]}"
  )
);

注意:在 Kotlin 的最新 Retrofit 版本(2.7.1)中,建议使用如下扩展方法:

Response.error(
  400,
  "{\"key\":[\"somestuff\"]}"
    .toResponseBody("application/json".toMediaTypeOrNull())
)

这属于有效的 Java 第 1 条:考虑静态工厂方法而不是构造函数.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在使用 Retrofit 2 进行单元测试期间创建 Retrofit.Response 对象 的相关文章

随机推荐