Skip to content

Instantly share code, notes, and snippets.

@lgawin
Created November 16, 2020 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lgawin/2cac08560c1b887acd222b2246e6db79 to your computer and use it in GitHub Desktop.
Save lgawin/2cac08560c1b887acd222b2246e6db79 to your computer and use it in GitHub Desktop.
package com.example.android.testing.blueprint
import android.content.res.AssetManager
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import retrofit2.Retrofit
/**
* Provides [OkHttpClient] that returns mocked data from `assets/[root]` folder
* based on [Request] data.
*
* Use it as a client for [Retrofit]:
* ```
* Retrofit.Builder()
* .baseUrl("http://fake.url")
* .client(assetsMocksHttpClient(assets, "mocks"))
* .addConverterFactory(GsonConverterFactory.create())
* .build()
* ```
*/
fun assetsMocksHttpClient(assets: AssetManager, root: String): OkHttpClient {
val pathResolver: (Request) -> String = { request ->
listOf(root)
.plus(request.url.pathSegments)
.joinToString("/", postfix = ".json")
}
val dataProvider: (String) -> MockData = { path ->
MockData(assets.open(path).bufferedReader().readText())
}
return OkHttpClient.Builder()
.addInterceptor(MockResponseInterceptor(pathResolver, dataProvider))
.build()
}
private class MockResponseInterceptor(
private val pathResolver: (Request) -> String,
private val dataProvider: (String) -> MockData
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response = with(chain.request()) {
try {
val path = pathResolver(this)
val (content, mediaType) = dataProvider(path)
ok(content, mediaType)
} catch (e: Exception) {
error(e.message!!, "plain/text")
}
}
private fun Request.ok(content: String, mediaType: String): Response =
response(200, "OK", content, mediaType)
private fun Request.error(content: String, mediaType: String): Response =
response(500, "Internal Server Error", content, mediaType)
private fun Request.response(
code: Int,
message: String,
content: String,
mediaType: String
) = Response.Builder()
.request(this)
.protocol(Protocol.HTTP_1_0)
.code(code)
.message(message)
.body(content.toResponseBody(mediaType.toMediaType()))
.build()
}
private data class MockData(val content: String, val mediaType: String = "application/json")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment