in Android, Testing

Running WireMock on Android

Update: (September 17th, 2017) – WireMock 2.8.0 is the latest working version on Android at this point in time.  Check out https://github.com/handstandsam/AndroidHttpMockingExamples and https://github.com/handstandsam/ShoppingApp for the latest examples as this blog post was written in January of 2016.


WireMock on Android is now possible!  Thanks to work by @tomakehurst with the 2.0-beta branch of WireMock to revamp the dependency structure from the 1.0 branch, and a tiny change I put in to match Android’s HttpClient method signatures, it can now run on Android without any modifications.

WireMock includes the following features out of the box which are very valuable in a wide variety of development and testing scenarios:

  • HTTP response stubbing, matchable on URL, header and body content patterns
  • Request verification
  • Runs in unit tests, as a standalone process or as a WAR app
  • Configurable via a fluent Java API, JSON files and JSON over HTTP
  • Record/playback of stubs
  • Fault injection
  • Per-request conditional proxying
  • Browser proxying for request inspection and replacement
  • Stateful behaviour simulation
  • Configurable response delays

It’s true you don’t have to put WireMock on your Android device to use it.  You can also just run WireMock on a computer and get a lot of benefit out of this by pointing your HTTP calls to your computer.  This can be very useful during development and testing, but will require you to manage these mock files separate from your Android application. When you run WireMock on your computer, you’re creating a configuration dependency which is challenging to maintain for scripted testing scenarios.  By including WireMock in your Android project and starting the server programmatically, you are able to remove the dependency of having to run an external server.

Here are your build.gradle dependencies to bundle WireMock 2.0.8-beta into your Android project:

compile("com.github.tomakehurst:wiremock:2.0.8-beta") {
    //Allows us to use the Android version of Apache httpclient instead
    exclude group: 'org.apache.httpcomponents', module: 'httpclient'

    //Resolves the Duplicate Class Exception
    //duplicate entry: org/objectweb/asm/AnnotationVisitor.class
    exclude group: 'asm', module: 'asm'

    //Fixes Warning conflict with Android's version of org.json
    //org.json:json:20090211 is ignored for debugAndroidTest as it may be conflicting with the internal version provided by Android.
    exclude group: 'org.json', module: 'json'
}
//Android compatible version of Apache httpclient.
compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'

If you want an example of what it looks like to use a bundled WireMock instance in an Android test, check out an examples repository on GitHub I put together to show this.

Here is an Espresso Test from the examples project:

@RunWith(AndroidJUnit4.class)
public class WireMockActivityInstrumentationTestCase2 extends ActivityInstrumentationTestCase2 {
    private MainActivity activity;

    public WireMockActivityInstrumentationTestCase2() {
        super(MainActivity.class);
    }

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(BuildConfig.PORT);

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        activity = getActivity();
    }
    @Test
    public void testWiremock() {
        String jsonBody = asset(activity, "atlanta-conditions.json");
        stubFor(get(urlMatching("/api/.*"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withBody(jsonBody)));

        String serviceEndpoint = "http://127.0.0.1:" + BuildConfig.PORT;
        activity.setWeatherServiceManager(new WeatherServiceManager(serviceEndpoint));

        onView(ViewMatchers.withId(R.id.editText)).perform(typeText("atlanta"));
        onView(withId(R.id.button)).perform(click());
        onView(withId(R.id.textView)).check(matches(withText(containsString("GA"))));
    }
}

Full Source File on GitHub

If you’re using WireMock for only testing or mock scenarios, you can justify the dependency overhead of including the library because of it’s vast array of features.  But, I wouldn’t suggest embedding it into your normal app as it has a very large method count and size footprint.  Here’s a breakdown of how big WireMock and it’s dependencies are:

Screen Shot 2016-01-30 at 8.23.55 PM
Source: http://www.methodscount.com/?lib=com.github.tomakehurst:wiremock:2.0.8-beta

That puts us at a total of 54,691 methods if you include WireMock 2.0.8-beta in your project by itself. Wowsa, that’s a lot, especially with Android’s 65,000 Method Limit (which can be circumvented using a technique called MultiDex).

Dependency exclusions & inclusions for WireMock to run on Android:

  • Exclude: org.apache.httpcomponents:httpclient (-4,098 Methods)
  • Exclude: org.json:json (-357 Methods)
  • Exclude: asm:asm (-391 Methods)
  • Include: org.apache.httpcomponents:httpclient-android (+3,389 Methods)

Grand Total Method Count for Android: 53,234

Grade dependencies tree for WireMock 2.0.8-beta:

+--- com.github.tomakehurst:wiremock:2.0.8-beta
|    +--- org.eclipse.jetty:jetty-server:9.2.13.v20150730
|    |    +--- javax.servlet:javax.servlet-api:3.1.0
|    |    +--- org.eclipse.jetty:jetty-http:9.2.13.v20150730
|    |    |    \--- org.eclipse.jetty:jetty-util:9.2.13.v20150730
|    |    \--- org.eclipse.jetty:jetty-io:9.2.13.v20150730
|    |         \--- org.eclipse.jetty:jetty-util:9.2.13.v20150730
|    +--- org.eclipse.jetty:jetty-servlet:9.2.13.v20150730
|    |    \--- org.eclipse.jetty:jetty-security:9.2.13.v20150730
|    |         \--- org.eclipse.jetty:jetty-server:9.2.13.v20150730 (*)
|    +--- org.eclipse.jetty:jetty-servlets:9.2.13.v20150730
|    |    +--- org.eclipse.jetty:jetty-continuation:9.2.13.v20150730
|    |    +--- org.eclipse.jetty:jetty-http:9.2.13.v20150730 (*)
|    |    +--- org.eclipse.jetty:jetty-util:9.2.13.v20150730
|    |    \--- org.eclipse.jetty:jetty-io:9.2.13.v20150730 (*)
|    +--- org.eclipse.jetty:jetty-webapp:9.2.13.v20150730
|    |    +--- org.eclipse.jetty:jetty-xml:9.2.13.v20150730
|    |    |    \--- org.eclipse.jetty:jetty-util:9.2.13.v20150730
|    |    \--- org.eclipse.jetty:jetty-servlet:9.2.13.v20150730 (*)
|    +--- com.google.guava:guava:18.0
|    +--- com.fasterxml.jackson.core:jackson-core:2.6.1
|    +--- com.fasterxml.jackson.core:jackson-annotations:2.6.1
|    +--- com.fasterxml.jackson.core:jackson-databind:2.6.1
|    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.6.0 -> 2.6.1
|    |    \--- com.fasterxml.jackson.core:jackson-core:2.6.1
|    +--- org.skyscreamer:jsonassert:1.2.3
|    +--- xmlunit:xmlunit:1.6
|    +--- com.jayway.jsonpath:json-path:2.0.0
|    |    +--- org.slf4j:slf4j-api:1.7.10 -> 1.7.12
|    |    \--- net.minidev:json-smart:2.1.1
|    |         \--- net.minidev:asm:1.0.2
|    +--- org.slf4j:slf4j-api:1.7.12
|    +--- net.sf.jopt-simple:jopt-simple:4.9
|    \--- junit:junit:4.12 (*)
\--- org.apache.httpcomponents:httpclient-android:4.3.5.1

My recommendation: If you need the features WireMock provides, go with it.  It’s sexy and it works well.  WireMock has a lot of bang for the buck, and you’re only taking this overhead in test and mock build flavors.  If you’re looking for something WAY more basic on Android, try okhttp’s MockWebServer project.  It does allow you to run an HTTP server within your app but it’s very limited and that makes it lightweight.  You can queue up responses in a row, or create a custom “dispatcher” which allows you to choose which response to send back based on a request.  It really depends on your use cases as to which one you choose.  There is also an example of MockWebServer being used in the same AndroidHttpMockingExamples project on GitHub.  Note: the examples are there mostly for configuration but don’t exercise all of WireMock’s features.  In this examples project, you will see that MockWebServer is an equally viable solution because of the simplicity of this use case.

The latest version of okhttp’s MockWebServer has 20,453 methods, but that includes okhttp and junit which you are probably already using in your project.  The biggest culprit is BouncyCastle (a java implementation of many encryption algorithms) which has 15,163 on it’s own.

Screen Shot 2016-01-30 at 9.54.32 PM

Source: http://www.methodscount.com/?lib=com.squareup.okhttp3:mockwebserver:3.0.1

Gradle Dependencies for okhttp’s MockWebServer:

\--- com.squareup.okhttp3:mockwebserver:3.0.1
     +--- com.squareup.okhttp3:okhttp:3.0.1
     |    \--- com.squareup.okio:okio:1.6.0
     +--- com.squareup.okhttp3:okhttp-ws:3.0.1
     |    \--- com.squareup.okhttp3:okhttp:3.0.1 (*)
     +--- org.bouncycastle:bcprov-jdk15on:1.50
     \--- junit:junit:4.11 -> 4.12 (*)

Related Info: If you just want a little more info and more advanced use cases about how to use WireMock on Android using Espresso UI tests, Michael Bailey has a great talk up on YouTube from 2014.  He talks about how he used an embedded WireMock instance on Android that he hacked together for version 1 of WireMock (library is not publicly available).  He shows some really good examples and I highly recommend watching the talk.

Finally: One thing I haven’t figured out how to do on Android yet is to use the “__files” and “mappings” directories the same way you can on a computer.  If anyone knows how to get this to work, or a nice work-around, please let me know.

Are you using WireMock on Android?  If so, please let me know on Twitter by tweeting @HandstandSam, I’d love to know.