Android mock retrofit response

An easier way is to ask the backend developer to create the API service and just send fake content for the sake of it. The underlying notion is that we are not backend developers and it is not our responsibility to provide the endpoint.

In this article, we’ll explore the option which involves using Interceptors offered by OkHttp to mock an API response. It’ll allow you to test your Retrofit REST service interface without changing anything on the code.

Interceptors

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls. Here’s a simple interceptor that logs the outgoing request and the incoming response.

https://square.github.io/okhttp/images/[email protected]

Interceptors Sample

public interface Interceptor { 
  Response intercept(Chain chain) throws IOException; 
  interface Chain { 
    Request request(); 
    Response proceed(Request request) throws IOException; 
    @Nullable Connection connection(); 
  } 
}

Interceptors from OkHttp are bad-ass and more powerful than you can think. They can be used in many different ways starting from logging to monitor the network calls our app makes and handling nasty situations. It allows you to rewrite requests to compress them or sign them or even transform the response body to workaround server problems.

In order to find a solution to our problem, we are prepared to deal with the consequences of rewriting response body because we are making a conscious call.

Create Mock Interceptor

Create a new class “MockInterceptor” and implements Interceptor on it. This will force the API response to use our own response the API call.

class MockInterceptor : Interceptor{


    override fun intercept(chain: Interceptor.Chain): Response {
        if (BuildConfig.DEBUG) {
            val uri = chain.request().url().uri().toString()
            val responseString = when {
                uri.endsWith("login") -> getListOfReposBeingStarredJson
                else -> ""
            }

            return chain.proceed(chain.request())
                .newBuilder()
                .code(200)
                .protocol(Protocol.HTTP_2)
                .message(responseString)
                .body(
                    ResponseBody.create(
                        MediaType.parse("application/json"),
                    responseString.toByteArray()))
                .addHeader("content-type", "application/json")
                .build()
        } else {
            //just to be on safe side.
            throw IllegalAccessError("MockInterceptor is only meant for Testing Purposes and " +
                    "bound to be used only with DEBUG mode")
        }
    }
}

const val getListOfReposBeingStarredJson = """
{"name":"velmm","address":"Chennai"}
"""

Create API Client

In my case I use Retrofit so I need to define its OkHttpClient explicitly to MockInterceptor onto it.

interface ApiService {

    @GET("login")
    fun login() : Call<LoginResponse>

}


object NetworkClient {

    fun create() : ApiService {

        return Retrofit.Builder()
            .client(OkHttpClient.Builder().addInterceptor(MockInterceptor()).build())
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http://www.mocky.io/v2/")
            .build().create(ApiService::class.java)

    }

}

Thats it. Now call the login API from your MainActivity. This should return your Mock response.

NetworkClient.create().login().enqueue(object: Callback<LoginResponse>{
            override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
                Log.d("Error",t.toString())
            }

            override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
              Log.d("Success",response.body().toString())
            }
        })
github_link

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top