Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do unit testing for retrofit2 callbacks?

I want to do an unit test that verifies if function1() or function2() were called. I haven't work with callbacks before, can you give me any idea about how to do it?

public void sendData(HttpService service, Document userData) {
    Call<String> call = service.updateDocument(getId(), userData);

    call.enqueue(new Callback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        function1(response.code());
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {
        function2();
    }
    });
}
like image 331
Jimmy A. León Avatar asked May 16 '16 16:05

Jimmy A. León


People also ask

How do you write a unit test for retrofit API calls?

To do this, we'll need to switch your Retrofit interface implementation, that you use to make calls with a mock, and do some fake responses taking advantage of Mockito ArgumentCaptor class. Proceed with the test by right clicking the test class and hitting run. And that's it.

What is retrofit testing?

Retrofit - probably the most popular networking client in Android development. Basically it allows to create HTTP client in an interface - you just add annotation with HTTP method, relative or absolute path and proper request is constructed.

What is retrofit callback?

Retrofit uses two different callback methods for the two possible outcomes of a network requests: either a failure or a successful request. Retrofit will call the appropriate callback method depending on the result. If the request was successful, Retrofit will also pass you the response of the server.

How do you test that a callback is working?

You register a callback with a class when you create it, and you have a method that communicates back via that callback. Here’s our class. To test this we want to test that the method passes the right result to the callback. We could use an anonymous function with an assert inside, but that test would pass even if the callback was never called.

Is it possible to convert call<T> to RX single in retrofit?

In my opinion the power of Retrofit comes from call and converter adapter factories - instead of relying on built-in types (such as retrofit2.Call) you can add RxJava call adapter and framework would find a way to convert Call<T> into rx Single<T>. Unfortunately we won't have direct access to Call.request () method then!

How to execute code in callback function in JUnit?

The JUnit framework never executes the code in the CallBack functions because the main thread of execution terminates before the response is retrieved. You can use CountDownLatch as shown below: This test sample may be helpful too. My advice isn't to perform testing for the API responses in the android app. There are many external tools for this.

When does the callback get invoked by FS?

However, that callback gets invoked by fs after its file read is complete, and since we’ll be mocking fs for our unit tests, how do we test that code?


1 Answers

I couldn't try, but it should work. Maybe you have to fix generic type casting errors like mock(Call.class);.

@Test
public void should_test_on_response(){
    Call<String> onResponseCall = mock(Call.class);

    doAnswer(invocation -> {
        Response response = null;
        invocation.getArgumentAt(0, Callback.class).onResponse(onResponseCall, response);
        return null;
    }).when(onResponseCall).enqueue(any(Callback.class));

    sendData(....);

    // verify function1
}

@Test
public void should_test_on_failure(){
    Call<String> onResponseCall = mock(Call.class);

    doAnswer(invocation -> {
        Exception ex = new RuntimeException();
        invocation.getArgumentAt(0, Callback.class).onFailure(onResponseCall, ex);
        return null;
    }).when(onResponseCall).enqueue(any(Callback.class));

    sendData(....);

    // verify function2
}
like image 166
utkusonmez Avatar answered Oct 18 '22 02:10

utkusonmez