Mockito + Dexmaker on Android

So the problem is with Dexmaker not being able to find the cache path on Android >= 4.3 as other people mentioned and as described in this dexmaker issue.

I went with implementing the workaround in a custom instrumented test runner instead of in every test (or their superclass) setUp(), because it feels a bit less hacky (it really is in only one place - and not inherited in every subclass) and more flexible. For the sake of documentation these are the necessary changes to do this:

public class CustomInstrumentationTestRunner extends InstrumentationTestRunner {

    @Override public void onCreate (final Bundle arguments) {
        super.onCreate(arguments);

        // temporary workaround for an incompatibility in current dexmaker (1.1) implementation and Android >= 4.3
        // cf. https://code.google.com/p/dexmaker/issues/detail?id=2 for details
        System.setProperty("dexmaker.dexcache", getTargetContext().getCacheDir().toString());
    }
}

And set up your project (or test project) to use this class as the instrumented test runner in its AndroidManifest.xml when building with ant:

<instrumentation
    android:name="my.package.CustomInstrumentationTestRunner"
    android:targetPackage="my.target.package" />

or its build.gradle when building with gradle:

android {
    defaultConfig {
        // ...
        testInstrumentationRunner 'my.package.CustomInstrumentationTestRunner'
    }
    // ...
}

If you have other instrumentation entries, you can switch between them either on the command line or select one in your IDE running configuration.


From @rjath's comment of @MrChaz's answer, this works better for me:

System.setProperty(
    "dexmaker.dexcache",
    getInstrumentation().getTargetContext().getCacheDir().getPath());

I put it in my setUp() method.


I've managed to piece together a fix that seems to be working for me. To the manifest I added read and write external storage. To the test I added System.setProperty("dexmaker.dexcache", "/sdcard"); to the test. To the emulator image I added an SD card.

I believe this works because by default mockito tries to use the apps cache directory but I never run an activity so I suspect the directory is never created by the OS