Skip to content

A wrapper around Square's MockWebserver that serves json files for easy testing

Notifications You must be signed in to change notification settings

icapps/MockingJ

Repository files navigation

MockingJ

Release

A wrapper around Square's MockWebserver that allows you to mock API responses by placing JSON files in a certain file structure. This will actually spawn a http server, which allows you to test your application without having to mock your network layer. Just use the baseUrl provided by the MockingJServer (or MockingJTestRule) instead of your normal base URL.

MockingJ comes with a JUnit TestRule (MockingJTestRule) and a @MockResponses annotation which allows for easy setup in your unit tests.

Please note that this library is experimental. It works, but it's still under development and may undergo breaking changes. Response matching is also very crude and probably not very reliable at the moment.

Quick start

Add the MockingJ dependency:

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }
dependencies {
            compile 'com.github.maartenvang:MockingJ:0.0.1-alpha2'
    }

Place your API responses as json files in your resources folder under /responses in the following structure:

src/test/resources/responses -- users.json
                             \_ users -- GET_1.json
                                      \_ GET_2.json
                                      \_ GET_*.json

The file name corresponds to the HTTP method used and the request URI. The filenames support wildcards. Non-wildcards and more specific filenames have priority over wildcards.

e.g. GET http://example.com/users/3 will match with the file responses/users/GET_*.JSON but GET http://example.com/users/2 will match GET_2.json because it has fewer wildcards.

Each file should contain the desired response in the following format:

{
  "responseCode": 200,
  "responseHeaders": {
    ...
  },
  "responseBody": {
    ...
  }
}

responseCode is required, responseHeaders and responseBody are optional. responseBody can either be a JSON object or an array.

Starting the mock server is easy:

val mockServer = MockingJServer()
val url = mockServer.start()

Note that if you use the test rule, starting your own server is not necessary.

Test example

A simple test setup could look like this:

@RunWith(JUnitRunner::class)
class ExampleTest {

    @Rule
    @JvmField
    val rule = MockingJTestRule(mockAll = false) // if mockAll == true (default), responses will be mocked for all tests without requiring a @MockResponses annotation

    @Test
    @MockResponses()
    fun testExample() {
        // Responses from /src/test/resources/responses will be used
    }

    @Test
    @MockResponses(overrideResponseDirectory = "responses-overridden")
    fun testAnotherExample() {
        /* Responses from /src/test/resources/responses-overridden will be used,
           if no response was found responses from /src/test/resources/responses will be used as fallback */
    }

}

You can then use MockingJ.baseUrl as baseURL for your API calls. A retrofit example with dagger2 could look like this:

@Module
class TestModule {

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
                .baseUrl(MockingJ.baseUrl ?: throw IllegalStateException("No valid baseURL available in testing environment"))
                .client(okHttpClient)
                .build()
    }

    @Provides
    @Singleton
    fun provideExampleService(retrofit: Retrofit): ExampleService {
        return retrofit.create(ExampleService::class.java)
    }

}