How to unit test retrofit web API calls

Viewed 274

I am trying to test my Service class that uses Retrofit to make @GET call.

I updated my test case and now I am using the mock-retrofit from square to mock the server following their test sample and some other examples here. But I am struggling to unit test the method that calls the retrofit interface.

The sample example of retrofit-mock tests the interface class. How can I mock the retrofit call for my method that implements the interface method.

public class XmattersApi {

    private XmattersInterface service;

    public GroupsResponse getGroupsWithSupervisor() throws IOException {
         String host = xmattersApiConfiguration.getHost();

         Interceptor interceptor = new Interceptor() {
             @Override
             public okhttp3.Response intercept(Chain chain) throws IOException {
                 Request newRequest = chain.request().newBuilder().addHeader("Authorization", "TestToken").build();
                 return chain.proceed(newRequest);
             }
         };

         OkHttpClient.Builder builder = new OkHttpClient.Builder();
         builder.interceptors().add(interceptor);
         OkHttpClient client = builder.build();

         Retrofit retrofit = new Retrofit.Builder()
                 .baseurl(getBaseUri(host).toUriString())
                 .addConverterFactory(JacksonConverterFactory.create())
                 .client(client)
                 .build();

         service = retrofit.create(XmattersInterface.class);

         Call<GroupsResponse> retrofitCall = service.getGroupsWithSupervisor("supervisors");

         Response<GroupsResponse> response = retrofitCall.execute();

         if (!response.isSuccessful()) {
             throw new IOException(response.errorBody() != null
                 ? response.errorBody().string(): "unknown error");
         }

         return response.body();

    }
}


My interface class defined below:

public interface XmattersInterface {

    @Headers({"Content-type: application/json;charset=UTF-8"})
    @GET("groups")
    Call<GroupsResponse> getGroupsWithSupervisor(@Query("embed") String embed);

}

I have tried mocking the retrofit call and returning the mocked response when the service interface is called.

It is not calling the mock. Here is my updated test case.

public class XmattersApiTest {

   XmattersApi xmattersAPi;

   XmattersInterfaceMock xmattersInterfaceMock;
  
   private final NetworkBehavior behavior = NetworkBehavior.create();


    @BeforeEach
    public void setUp() throws Exception {
        Retrofit retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(JacksonConverterFactory.create())
                .baseUrl("http://example.com").build();
        MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).networkBehavior(behavior).build();

       final BehaviorDelegate<XmattersInterface> delegate = mockRetrofit.create(XmattersInterface.class);

       xmattersInterfaceMock = new XmattersInterfaceMock(delegate);

    }

    @Test
    void testGroupsWithSupervisorCase_1() throws IOException {

       Call<GroupsResponse> call = mock(Call.class);
       XmattersInterface xmattersInterface =  mock(XmattersInterface.class)

       Call<GroupsResponse> mockCall = xmattersInterfaceMock.getGroupsWithSupervisor("supervisors");
       Response<GroupsResponse> mockResponse = mockCall.execute; // Mock data is received here from the XmattersInterfaceMock
       when(xmattersInterface.getGroupsWithSupervisor(ArgumentMatchers.anyString())).thenReturn(mockCall); 

       when(call.execute()).thenReturn(mockResponse)
       xmattersApi.getGroupsWithSupervisor(); //Fails with java.net.SocketTimeoutException error


    }

}

The service mock class to delegate the request:

public class XmattersInterfaceMock implements XmattersInterface {
    private final BehaviorDelegate<XmattersInterface> delegate;

    public XmattersInterfaceMock(BehaviorDelegate<XmattersInterface> delegate) {
        this.delegate = delegate;
    }

    @Override
    public Call<GroupsResponse> getGroupsWithSupervisor(String embed) {
        return delegate.returningResponse(getMockGroupsResponse()).getGroupsWithSupervisor(embed);
    }
}

What am I doing wrong here? Someone please help!

I am using Springboot- JUnit, mockito

0 Answers
Related