Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Retrofit LocalJsonClient

A Retrofit Client that reads JSON files from disk and returns them as the response (to be handled by GSON). Make sure the context you pass is from the instrumentation app and put your JSON files in res/raw in the instrumentation project. Inspired by Ruby's vcr gem.

A GET request to /articles will look for the JSON file res/raw/get_articles.json, a POST request to /articles/123/ will look for the JSON file res/raw/post_articles_123.json, etc.

We use setScenario() if we want to test alternate responses so that a failed login POST to /login will read from res/raw/failed_login_post_login.json (and the happy path can use post_login.json).

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import retrofit.client.Client;
import retrofit.client.Header;
import retrofit.client.Request;
import retrofit.client.Response;
import retrofit.mime.TypedInput;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
@SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client {
private Context context;
private String scenario = null;
public LocalJsonClient(Context ctx) {
this.context = ctx;
}
public void setScenario(String scenario) {
this.scenario = scenario;
}
@Override
public Response execute(Request request) throws IOException {
URL requestedUrl = new URL(request.getUrl());
String requestedMethod = request.getMethod();
String prefix = "";
if (this.scenario != null) {
prefix = scenario + "_";
}
String fileName = (prefix + requestedMethod + requestedUrl.getPath()).replace("/", "_");
fileName = fileName.toLowerCase();
int resourceId = context.getResources().getIdentifier(fileName, "raw",
context.getPackageName());
if (resourceId == 0) {
Log.wtf("YourTag", "Could not find res/raw/" + fileName + ".json");
throw new IOException("Could not find res/raw/" + fileName + ".json");
}
InputStream inputStream = context.getResources().openRawResource(resourceId);
String mimeType = URLConnection.guessContentTypeFromStream(inputStream);
if (mimeType == null) {
mimeType = "application/json";
}
TypedInput body = new TypedInputStream(mimeType, inputStream.available(), inputStream);
return new Response(request.getUrl(), 200, "Content from res/raw/" + fileName, new ArrayList<Header>(), body);
}
private static class TypedInputStream implements TypedInput {
private final String mimeType;
private final long length;
private final InputStream stream;
private TypedInputStream(String mimeType, long length, InputStream stream) {
this.mimeType = mimeType;
this.length = length;
this.stream = stream;
}
@Override
public String mimeType() {
return mimeType;
}
@Override
public long length() {
return length;
}
@Override
public InputStream in() throws IOException {
return stream;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment