Mockito + Dexmaker on Android

妖精的绣舞 提交于 2019-11-27 20:01:20

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

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.

I had this issue for an Android Library project but NOT for the application project! Setting the System property "dexmaker.dexcache" as mentioned above worked around the issue. I'm running Android 4.3 Nexus 4 device, building with 19.0.3 tools, target api 19, my dependencies:

androidTestCompile "org.mockito:mockito-core:1.9.5"
androidTestCompile "com.google.dexmaker:dexmaker:1.0"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.0"
Stan Kurdziel

It looks like the dexmaker project has moved from Google Code to GitHub.

In the maven central repository there are versions 1.1 and 1.2 published in March 2014 and December 2014.

I've verified this "dexcache == null" issue still exists through version 1.2 - but only on certain devices. For example, a Galaxy S5 with Android 5.0 has the problem, and a Galaxy S4 with Android 4.4.2 does not.

I cloned the GitHub repository (last commit March 12th 2015 - ca74669), and ran locally, and the problem has been fixed (there are also commits in the history that back this up). So once there is a 1.3 release, hopefully this problem is gone for good!

Anyone else wanting to run a local copy of 1.3-SNAPSHOT, here's how I did that (on a Mac, but other platforms should work too, you'll need mvn, adb, and dx on PATH):

  1. git clonehttps://github.com/crittercism/dexmaker.git
  2. cd dexmaker
  3. mvn install -Dmaven.test.skip=true
  4. cp -R ~/.m2/repository/com/google/dexmaker $ANDROID_HOME/extras/android/m2repository/com/google
  5. Then change version in app/build.gradle: androidTestCompile 'com.google.dexmaker:dexmaker:1.3-SNAPSHOT'
    • Or pom.xml if using maven to build, or overwrite your libs/dexmaker.jar with ~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar if you are using eclipse/ant

Also, FYI, the original issue report for the same issue on Google Code as well.

You can add the mockito core as a dependency instead. Then, that error will not happen and you won't need a workaround.

dependencies {
   ... 
   testCompile 'org.mockito:mockito-core:1.10.19'
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!