How to create a retrofit.Response object during Unit Testing with Retrofit 2

While using RxJava and Retrofit 2 I am trying to create Unit Tests to cover when my app receives specific responses.

The issue I have is that with Retrofit 2 I cannot see a nice way of creating a retrofit.Response object without the use of reflection.

  • How to check the size of dependencies in an android app?
  • Android Remove file with DDMS
  • Listing of manufacturer's clock / alarm package and class name, Please add
  • RxJava + Retrofit -> BaseObservable for API calls for centralized response handling
  • Meta Tag “apple-mobile-web-app-capable” for Android?
  • Android soft Keyboard not open in webView`
  • @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);
    }
    

    I have tried using the following but this creates an OkHttp Response vs a Retrofit Response.

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

    Related posts:

    Android crash with translucent splash screen
    How can I get the first name (or full name) of the user of the phone?
    Is it possible to get the mac address of client devices which are within wifi hotspot range?
    How to read USSD messages in android?
    Class not found when Unmarshalling Android Intent Parcelable
    How do I prevent Android Studio from automatically collapsing my packages in project navigation?
  • Add the loading screen in starting of the android application
  • How to use SortedList in RecyclerView with Android data binding library?
  • Using libVLC for Android on windows platform
  • Android Google Map to show as picture
  • Android:To set an item as selected when the ListView opens?
  • Unit Test an Android Fragment
  • One Solution collect form web for “How to create a retrofit.Response object during Unit Testing with Retrofit 2”

    The retrofit.Response class has static factory methods to create 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) {
      /* ... */
    }
    

    For example:

    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\"]}"
      )
    );
    

    This falls under Effective Java Item 1: Consider static factory methods instead of constructors.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.