Skip to content

donfuxx/Mockinizer

Repository files navigation

Mockinizer Build Status

An OkHttpClient / RetroFit web api call mocking library that uses MockWebServer to provide mocked responses by using Interceptors.

What is it?

Mockinizer helps Android developers to build apps with web api calls that use OkHttpClient / RetroFit by allowing them to quickly mock some web api responses with MockWebServer. Mockinizer allows to mock only specific api calls, while other api calls will still call the original server. This is particularily usefull in the following scenarios:

  • You are working on a new feature that needs to call new not yet existing apis. With Mockinizer you can quickly swap in the new desired mocked api responses while other api calls will still use the real server
  • You want to test error cases for existing apis. With Mockinizer you can can quickly mock an error 500 response or an 401 Unauthorized for selected api requests and verify if your app handles them gracefully
  • You want to call a mocked api for unit testing and isolate those from the webserver

Setup

1. Add jitpack.io repository:

Add jitpack.io repository in root build.gradle:

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

2. Add Mockinizer gradle dependency

Add the below code in the app module's build.gradle (Usually you want to implement it only in debug builds and not release builds) At the time of writing the latest mockinizer_version was 1.1.0, you can get latest release version here: https://github.com/donfuxx/Mockinizer/releases

dependencies {
    debugImplementation "com.github.donfuxx:Mockinizer:1.6.0"
}

You may also need to add a MockWebServer dependency in your app module:

dependencies {
    implementation "com.squareup.okhttp3:mockwebserver:4.0.1"
}

3. Define the RequestFilter / MockResponse Pairs

Those represent each api call that you want to mock. The RequestFilter defines the Request Path (relative to the RetroFit Baseurl) and/or the json body of the request. The MockResponse is the desired Response that you want to get returned by your local MockWebServer. See a simple example that defines 2 mock responses where one out of them is an error:

package com.appham.mockinizer.demo

import com.appham.mockinizer.RequestFilter
import okhttp3.mockwebserver.MockResponse

val mocks: Map<RequestFilter, MockResponse> = mapOf(

    RequestFilter("/mocked") to MockResponse().apply {
        setResponseCode(200)
        setBody("""{"title": "Banana Mock"}""")
    },

    RequestFilter("/mockedError") to MockResponse().apply {
        setResponseCode(400)
    }

)

4. Add mockinizer to OkHttpClient

To wire up the mocks that you defined in step 3 you just have to call the mockinize(mocks) extension function in the OkHttpClient builder and provide the mocks map as the parameter, see example:

OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .mockinize(mocks) // <-- just add this line
            .build()

Yes, that is it! Just add .mockinize(mocks) into the OkHttpClient.Builder chain. Happy mocking! :-)

5. Launch app and check logs to verify mocking is working

Once you call a mockinized api endpoint in your app then you can verify the mocked responses in the logcat. The attached HttpLogging interceptor should produce logs similar to:

D/OkHttp: --> GET https://my-json-server.typicode.com/typicode/demo/mockedError
D/OkHttp: --> END GET
D/OkHttp: --> GET https://my-json-server.typicode.com/typicode/demo/mocked
D/OkHttp: --> END GET
D/OkHttp: --> GET https://my-json-server.typicode.com/typicode/demo/posts
D/OkHttp: --> END GET
D/OkHttp: <-- 400 https://localhost:34567/typicode/demo/mockedError (97ms)
D/OkHttp: content-length: 0
D/OkHttp: mockinizer: <-- Real request /typicode/demo/mockedError is now mocked to HTTP/1.1 400 Client Error
D/OkHttp: server: Mockinizer 1.6.0 by Thomas Fuchs-Martin
D/OkHttp: <-- END HTTP (0-byte body)
D/OkHttp: <-- 200 https://localhost:34567/typicode/demo/mocked (104ms)
D/OkHttp: content-length: 98
D/OkHttp: mockinizer: <-- Real request /typicode/demo/mocked is now mocked to HTTP/1.1 200 OK
D/OkHttp: server: Mockinizer 1.6.0 by Thomas Fuchs-Martin
D/OkHttp: [
D/OkHttp:   {
D/OkHttp:     "id": 555,
D/OkHttp:     "title": "Banana Mock"
D/OkHttp:   },
D/OkHttp:   {
D/OkHttp:     "id": 675,
D/OkHttp:     "title": "foooo"
D/OkHttp:   }
D/OkHttp: ]
D/OkHttp: <-- END HTTP (98-byte body)
D/OkHttp: <-- 200 https://my-json-server.typicode.com/typicode/demo/posts (1416ms)
D/OkHttp: date: Sat, 28 Mar 2020 19:11:32 GMT
D/OkHttp: content-type: application/json; charset=utf-8
D/OkHttp: set-cookie: __cfduid=de53d4c305959e69c3e8ea1e6b78959001585422691; expires=Mon, 27-Apr-20 19:11:31 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax
D/OkHttp: x-powered-by: Express
D/OkHttp: vary: Origin, Accept-Encoding
D/OkHttp: access-control-allow-credentials: true
D/OkHttp: cache-control: no-cache
D/OkHttp: pragma: no-cache
D/OkHttp: expires: -1
D/OkHttp: x-content-type-options: nosniff
D/OkHttp: etag: W/"86-YtXc+x6dfp/4aT8kTDdp4oV+9kU"
D/OkHttp: via: 1.1 vegur
D/OkHttp: cf-cache-status: DYNAMIC
D/OkHttp: expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
D/OkHttp: server: cloudflare
D/OkHttp: cf-ray: 57b3a8502b8a71f7-AMS
D/OkHttp: [
D/OkHttp:   {
D/OkHttp:     "id": 1,
D/OkHttp:     "title": "Post 1"
D/OkHttp:   },
D/OkHttp:   {
D/OkHttp:     "id": 2,
D/OkHttp:     "title": "Post 2"
D/OkHttp:   },
D/OkHttp:   {
D/OkHttp:     "id": 3,
D/OkHttp:     "title": "Post 3"
D/OkHttp:   }
D/OkHttp: ]
D/OkHttp: <-- END HTTP (134-byte body)

In above example three api calls have been made. The only api call that wasn´t mocked is the call to https://my-json-server.typicode.com/typicode/demo/posts the other calls to /mocked and /mockedError got swapped in by Mockinizer! (Notice localhost responding to those with the previously defined mock responses)

See Mockinizer Demo Project

In case you want to see how it works in action then just check out the Mockinizer demo project!

Run automated tests

Another good way to see Mockinizer in action is to run the androidTests: just run ./gradlew build connectedCheck from the terminal and see in the logcat how api calls got mocked!

Contributing

Pull requests are welcome! Just fork Mockinizer and add submit your PR. Also feel free to add issues for new feature requests and discovered bugs. Check the Contributing guidelines for more infos.

Feedback

If you like this project then please don't forget to stargaze Mockinizer and share it with your friends!

Stay up to date

Always be the first to know about new releases and add Mockinizer to your watches.