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.
interface Interceptor {
@Throws(IOException::class)
fun intercept(chain: Chain?): Response?
interface Chain {
fun request(): Request?
@Throws(IOException::class)
fun proceed(request: Request?): Response?
@Nullable
fun connection(): Connection?
}
}
Interceptors from OkHttp are more powerful than you can think. They can be used in many different ways starting from logging in to monitoring 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 the response body because we are making a conscious call.
Mock API Response Example
Creating the Mock Interceptor
Create a new class MockInterceptor and implements Interceptor on it. This will force the API response to use our own response to the API call.
class MockInterceptor : Interceptor{
override fun intercept(chain: Interceptor.Chain): Response {
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()
}
}
const val getListOfReposBeingStarredJson = ""
{"name":"velmurugan","address":"Chennai 600096"}
""
Create API Client
In this case, I use Retrofit so I need to define its OkHttpClient
explicitly to MockInterceptor onto it.
In this tutorial, I am not explaining the retrofit in detail. check my other post for more detail on retrofit.
Retrofit android example kotlin[step by step] – Howtodoandroid
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)
}
}
We are done with the mock interceptor and API client setup. The next, step is to call the API from our main activity and display the mock data.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
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())
}
})
}
}
Mock API on Debug Mode Only
To mock the API only on debug mode, we need to check that BuildConfig is debugged. If it’s debugging mode then we can return the mock response.
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")
}
}
}
Conclusion
This mock API response method is very useful when we have some issues with the API’s response. Also, useful test different response types without much effort.
Thanks for reading. let me know your feedback in the comments. Also, you can download this example from GITHUB.
Android-Example/MockApiRetrofitAndroid at master · velmurugan-murugesan/Android-Example (github.com)
Leave a Reply