web-dev-qa-db-fra.com

Comment créer un objet retrofit.Response pendant les tests unitaires avec Retrofit 2

Lorsque j'utilise RxJava et Retrofit 2, j'essaie de créer des tests unitaires pour couvrir le moment où mon application reçoit des réponses spécifiques.

Le problème que j'ai, c'est qu'avec Retrofit 2, je ne peux pas voir une belle façon de créer un objet retrofit.Response sans utiliser de réflexion.

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

J'ai essayé d'utiliser ce qui suit mais cela crée une réponse OkHttp vs une réponse 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);
34
Graham Smith

Le retrofit.Response La classe a des méthodes d'usine statiques pour créer des instances:

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) {
  /* ... */
}

Par exemple:

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

Ou:

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

Cela relève de Efficace Java Item 1: Considérez les méthodes d'usine statiques au lieu des constructeurs .

52
nhaarman