Kotlin library to intercept Retrofit requests and provide a static JSON instead of remote response
Top level build.gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Module level build.gradle
dependencies {
implementation "com.github.javaherisaber.MockFit:runtime:$versions.mockFit"
kapt "com.github.javaherisaber.MockFit:compiler:$versions.mockFit" // for Kotlin (make sure to include kapt plugin also)
annotationProcessor "com.github.javaherisaber.MockFit:compiler:$versions.mockFit" // for Java
}
- Create json file of your api response lets say
picsum_list.json
and put it inassets/mock_json
directory
[
{
"id": "1016",
"author": "Andrew Ridley",
"width": 3844,
"height": 2563,
"url": "https://unsplash.com/photos/_h7aBovKia4",
"download_url": "https://picsum.photos/id/1018/3914/2935"
},
{
"id": "1018",
"author": "Andrew Ridley",
"width": 3914,
"height": 2935,
"url": "https://unsplash.com/photos/Kt5hRENuotI",
"download_url": "https://picsum.photos/id/1018/3914/2935"
},
{
"id": "1019",
"author": "Patrick Fore",
"width": 5472,
"height": 3648,
"url": "https://unsplash.com/photos/V6s1cmE39XM",
"download_url": "https://picsum.photos/id/1019/5472/3648"
}
]
- Define your api interface and annotate endpoint with
@mock("picsum_list.json")
so that Mockfit can generate config for you
interface Api {
@Mock("picsum_list.json")
@GET("list")
fun getListOfPicsums(
@Query("page") page: Int,
@Query("limit") limit: Int
): Call<List<Picsum>>
// if you want to filter through query params
@Mock("picsum_recent.json", excludeQueries = ["type=favorites"])
@GET("list")
fun getRecentPicsums(
@Query("type") type: String,
@Query("page") page: Int,
@Query("limit") limit: Int
): Call<List<Picsum>>
// if you want to filter through query params
@Mock("picsum_favorites.json", includeQueries = ["type=favorites"])
@GET("list")
fun getFavoritePicsums(
@Query("type") type: String,
@Query("page") page: Int,
@Query("limit") limit: Int
): Call<List<Picsum>>
}
- Add
MockfitInterceptor
to retrofit configuration
class RemoteDataSource(private val context: Context) {
fun api(): Api {
val mockFitInterceptor = provideMockFitInterceptor(context)
val okHttpClient = provideOkHttpClient(mockFitInterceptor)
val retrofit = provideRetrofit(okHttpClient)
return retrofit.create(Api::class.java)
}
private fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
private fun provideMockFitInterceptor(context: Context) = MockFitInterceptor(
bodyFactory = { input -> context.resources.assets.open(input) }, // read asset file
logger = { tag, message -> Log.d(tag, message) }, // pass logger to log events in logcat
baseUrl = BASE_URL, // base url of your api
requestPathToMockPathRule = REQUEST_TO_JSON, // autogenerated constant, just press build button
mockFilesPath = MOCK_FILES_PATH, // path to json files
mockFitEnable = true, // master setting to enable or disable mocking
apiEnableMock = true, // enable or disable mock when there are includes and excludes configs
apiIncludeIntoMock = arrayOf(), // include endpoint if `apiEnableMock` is false
apiExcludeFromMock = arrayOf(), // exclude endpoint if `apiEnableMock` is true
apiResponseLatency = 500L // latency of retrieving data
)
private fun provideOkHttpClient(mockFitInterceptor: MockFitInterceptor) = OkHttpClient.Builder()
.addInterceptor(mockFitInterceptor)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.build()
companion object {
private const val BASE_URL = "https://picsum.photos/v2/"
private const val MOCK_FILES_PATH = "mock_json" // located at assets/mock_json/
private const val CONNECT_TIMEOUT = 20L
private const val WRITE_TIMEOUT = 20L
private const val READ_TIMEOUT = 30L
}
}
- Rebuild (or just build current module)