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).
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.
@jaredculp
make sure you're linking to the correct method. https://github.com/square/retrofit/blob/5c2f505a974d84763b3c2279128351b8a73a3e2d/retrofit-mock/src/main/java/retrofit2/mock/Calls.java#L37
and not https://github.com/square/retrofit/blob/5c2f505a974d84763b3c2279128351b8a73a3e2d/retrofit-mock/src/main/java/retrofit2/mock/Calls.java#L41
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));
Most helpful comment
Thanks @NightlyNexus, looks like the compiler just needed a bit of help: