MockFit icon indicating copy to clipboard operation
MockFit copied to clipboard

Kotlin library to intercept http responses that fits into retrofit

MockFit

Download

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)