Android

Mock API response in Retrofit using custom clients

Praveena Kumara D

05 May 2015

Mock API response in Retrofit using custom clients

The advent of the retrofit library has made the API integration a lot smoother.It makes the code more manageable as we define All API’s at one place inside an interface.Retrofit works beautifully converting the API’s JSON response into workable java objects. Consuming these workable objects directly without requiring to write his/her own parsing is of great help to developers.

As the App functionality relies on API’s response converted workable java objects, it’s sort of creates a dependency as well. If you are a serious app developer, you know that during the development phase, client APIs are bound to be broken. In these cases ( which occur during the parallel development of App and APIs at server mostly) App development takes a hit. App developer will not be able to continue further till the Server team fixes API at their end.

Isn’t there a better way to sort of hard code the responses for different API’s and continue development? Most importantly by not introducing too much of boilerplate code which will be problematic to manage once the API’s are back?

Well, Retforit itself provides a simple way to achieve this.In this way, by just commenting a line you can switch between hardcoded response and real server integration.

Retrofit allows you create your own client to mange the request and response. In the below code you can see  that we have created a Mock client instead of a OK http client .

RestAdapter restAdapter = new RestAdapter.Builder()
 
  .setLogLevel(RestAdapter.LogLevel.FULL)
 
  .setEndpoint(BASE_URL)
 
  .setConverter(new GsonConverter(gson))
 
  // commented okhhtpclient .setClient(new OkClient(OkHttpSingleTonClass.getOkHttpClient()))
 
  .setClient(new MockClient(context)) //our Mock Client
 
  .build();

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

Now we can write the Mockclient.

public class MockClient implements Client {
 
 
 
  Context context;
 
 
 
  MockClient(Context context)
 
  {
 
  this.context=context;
 
  }
 
  @Override
 
  public Response execute(Request request) throws IOException {
 
  Uri uri = Uri.parse(request.getUrl());
 
 
 
  Log.d("MOCK SERVER", "fetching uri: " + uri.toString());
 
 
 
  String filename=uri.getPath();
 
  filename = filename.substring(filename.lastIndexOf('/') + 1).split("?")[0];
 
 
 
  try {
 
  Thread.sleep(2500);
 
  } catch (InterruptedException e) {
 
  e.printStackTrace();
 
  }
 
  InputStream is = context.getAssets().open(filename.toLowerCase()+".txt");
 
  int size = is.available();
 
  byte[] buffer = new byte[size];
 
  is.read(buffer);
 
  is.close();
 
  String responseString = new String(buffer);
 
  return new Response(request.getUrl(), 200, "nothing", Collections.EMPTY_LIST, new TypedByteArray("application/json", responseString.getBytes()));
 
  }
 
  }

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 If you look at the code, Mockclient is written to  read the Request URL and look for the corresponding file under assets folder.

For ex:

    @POST(“/activate”)

public void activate(@Body Request reqdata, Callback callback);

Here the mock client, understands that the URL being fired is activate and looks for a file named activate.txt in the assets folder.It reads the content from assets/activate.txt file and sends it as response for the API.

By using Mock client developer can continue working with the Api not really depending on APIs functioning. Note that we have Thread.sleep(2500) just to simulate some time delay before we get the response. This way we can ensure that the Progress loaders are also accommodated.

Obviously this is a test setup useful during the development/testing process.If you want to switch to the real server, you can comment the mock client and continue to use the OKhttp client.You can choose to delete those response files before you do a final integration with server ApIs and ship the app.