Square retrofit server mock for testing
Solution 1:
Mock Retrofit 2.0 Requests for Testing
As the old mechanisms like creating MockClient
class and implementing it from Client
are not working anymore with Retrofit 2.0, here I describe a new way of doing that. All what you need to do now is to add your custom interceptors for OkHttpClient like it is shown below. FakeInterceptor
class just overrides intercept
method and in the case if application is in DEBUG
mode return given JSON.
RestClient.java
public final class RestClient {
private static IRestService mRestService = null;
public static IRestService getClient() {
if(mRestService == null) {
final OkHttpClient client = new OkHttpClient();
// ***YOUR CUSTOM INTERCEPTOR GOES HERE***
client.interceptors().add(new FakeInterceptor());
final Retrofit retrofit = new Retrofit.Builder()
// Using custom Jackson Converter to parse JSON
// Add dependencies:
// com.squareup.retrofit:converter-jackson:2.0.0-beta2
.addConverterFactory(JacksonConverterFactory.create())
// Endpoint
.baseUrl(IRestService.ENDPOINT)
.client(client)
.build();
mRestService = retrofit.create(IRestService.class);
}
return mRestService;
}
}
IRestService.java
public interface IRestService {
String ENDPOINT = "http://www.vavian.com/";
@GET("/")
Call<Teacher> getTeacherById(@Query("id") final String id);
}
FakeInterceptor.java
public class FakeInterceptor implements Interceptor {
// FAKE RESPONSES.
private final static String TEACHER_ID_1 = "{\"id\":1,\"age\":28,\"name\":\"Victor Apoyan\"}";
private final static String TEACHER_ID_2 = "{\"id\":1,\"age\":16,\"name\":\"Tovmas Apoyan\"}";
@Override
public Response intercept(Chain chain) throws IOException {
Response response = null;
if(BuildConfig.DEBUG) {
String responseString;
// Get Request URI.
final URI uri = chain.request().url().uri();
// Get Query String.
final String query = uri.getQuery();
// Parse the Query String.
final String[] parsedQuery = query.split("=");
if(parsedQuery[0].equalsIgnoreCase("id") && parsedQuery[1].equalsIgnoreCase("1")) {
responseString = TEACHER_ID_1;
}
else if(parsedQuery[0].equalsIgnoreCase("id") && parsedQuery[1].equalsIgnoreCase("2")){
responseString = TEACHER_ID_2;
}
else {
responseString = "";
}
response = new Response.Builder()
.code(200)
.message(responseString)
.request(chain.request())
.protocol(Protocol.HTTP_1_0)
.body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()))
.addHeader("content-type", "application/json")
.build();
}
else {
response = chain.proceed(chain.request());
}
return response;
}
}
Source code of project on GitHub
Solution 2:
I decided to try method 1 as follows
public class MockClient implements Client {
@Override
public Response execute(Request request) throws IOException {
Uri uri = Uri.parse(request.getUrl());
Log.d("MOCK SERVER", "fetching uri: " + uri.toString());
String responseString = "";
if(uri.getPath().equals("/path/of/interest")) {
responseString = "JSON STRING HERE";
} else {
responseString = "OTHER JSON RESPONSE STRING";
}
return new Response(request.getUrl(), 200, "nothing", Collections.EMPTY_LIST, new TypedByteArray("application/json", responseString.getBytes()));
}
}
And using it by:
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setClient(new MockClient());
It works well and allows you to test your json strings without having to contact the real server!
Solution 3:
Testing JSON deserialization to your objects (presumably with TypeAdapters
?) seems like a separate problem that require separate unit tests.
I use version 2 personally. It affords type-safe, refactor-friendly code that can be easily debugged and altered. After all, what good is declaring your API as interfaces if you aren't creating alternate versions of them for testing! Polymorphism for the win.
Another option is using a Java Proxy
. This is actually how Retrofit (currently) implements its underlying HTTP interaction. This will admittedly require more work, but would allow for much more dynamic mocks.
Solution 4:
You can also use something like Webservermock from Squareup! --> https://github.com/square/okhttp/tree/master/mockwebserver