MockFit

Additional

Language
Kotlin
Version
2.0.0 (Mar 19, 2023)
Created
Nov 2, 2020
Updated
Sep 28, 2023
Owner
Mahdi Javaheri (javaherisaber)
Contributors
Hussein Habibi Juybari (Husseinhj)
Mahdi Javaheri (javaherisaber)
2
Activity
Badge
Generate
Download
Source code

MockFit

Kotlin library to intercept http responses that fits into retrofit

Dependency

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
}

How to use

  1. Create json file of your api response lets say picsum_list.json and put it in assets/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"
  }
]
  1. 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>>
}
  1. 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
    }
}
  1. Rebuild (or just build current module)