Retrofit: [Feature request] Mocking for Call<Void> responses

Created on 22 Jan 2018  路  7Comments  路  Source: square/retrofit

Given the following example:

public interface Example {
    @GET
    public Call<MyObject> getThingy();
        @POST
        public Call<Void> postThingy();
}

to mock the response for the GET request, I do something like:

MyObject object = new MyObject();
Call<MyObject> response = Calls.response(object);
when(example.getThingy()).thenReturn(response);

But when I try to do the same for the second request

Constructor<Void> voidConstructor = Void.class.getDeclaredConstructor();
voidConstructor.setAccessible(true);
Void voidMock = voidConstructor.newInstance();
Call<Void> response = Calls.response(voidMock);
when(example.postThingy()).thenReturn(response);

NPE is thrown (I tried some other approaches to this, but every time NPE was thrown; this was the one most likely to work) at response.enqueue

        response.enqueue(new Callback<Void>() {
            @Override
            public void onResponse(Call<Void> call, Response<Void> response) {
               //Do something
            }

            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                //Do something
            }
        });

Is it possible for Call<Void> response = Calls.response(voidMock); to return a response that will not throw a NPE? (or maybe there is another way to test the postThingy() method; I didn't manage to find any, since there is scarce info on how to mock Call<> responses... took me a lot of time to find what I wrote above).

Most helpful comment

Thanks @NightlyNexus, looks like the compiler just needed a bit of help:

interface Client {
  Call<Void> request();
}

when(client.request()).thenReturn(Calls.response((Void) null));

All 7 comments

Void is an instance-less type in Java. The only value value for it is null. You should use Calls.response(null). This method was missing a @Nullable annotation which has been fixed on master and will go out with 2.3.0 which should be in the next week or two.

Thank you for fast and clear reply. Will be waiting for the next version. Good luck and happy coding.

Hi @JakeWharton
This issue is not fixed in version 2.3.0. Calls.response(null) throws an AssertionError with the following message: Only one of response or error can be set. (the message is not accurate nor suggestive)
From what i saw, FakeCall class is not handling response == null cases yet, so can you please re-open the issue, or write a comment with an update on the issue?

I meant 2.4.0

This still doesn't work on 2.4.0 since FakeCall expects at least one of the response or error to be non-null.

Thanks @NightlyNexus, looks like the compiler just needed a bit of help:

interface Client {
  Call<Void> request();
}

when(client.request()).thenReturn(Calls.response((Void) null));
Was this page helpful?
0 / 5 - 0 ratings