Android上的Mockito + Dexmaker

时间:2012-09-04 16:19:12

标签: android mockito dexmaker

我正在尝试在我的Android项目中使用Mockito。 我找到了非常好的教程来处理它:http://www.paulbutcher.com/2012/05/mockito-on-android-step-by-step/

基本上它使用新版的Mockito + Dexmaker,一切都按预期工作 但是,当我尝试模拟一些Android特定对象时,即:

Context context = mock(Context.class);

我收到此例外:

java.lang.IllegalArgumentException: 
    dexcache == null (and no default could be found; 
    consider setting the 'dexmaker.dexcache' system property)
at com.google.dexmaker.DexMaker.generateAndLoad(DexMaker.java:359)
at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:252)
at com.google.dexmaker.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:54)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)

知道怎么解决吗?

7 个答案:

答案 0 :(得分:33)

来自@ rjath对@ MrChaz答案的评论,这对我来说效果更好:

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

我把它放在我的setUp()方法中。

答案 1 :(得分:10)

我设法拼凑了一个似乎对我有用的修复程序。 我在清单中添加了读写外部存储。 为了测试,我在测试中添加了System.setProperty("dexmaker.dexcache", "/sdcard");。 我在模拟器图像中添加了一张SD卡。

我相信这是有效的,因为默认情况下mockito尝试使用apps缓存目录,但我从未运行过活动,所以我怀疑该目录永远不会被操作系统创建

答案 2 :(得分:8)

问题在于Dexmaker无法像其他人提到的那样在Android> = 4.3上找到缓存路径,如this dexmaker issue中所述。

我在自定义检测测试运行器中实现了解决方法,而不是在每个测试(或他们的超类)setUp()中实现,因为它感觉不那么hacky(它实际上只在一个地方 - 而不是继承在每个子类中)并且更灵活。 为了记录起见,这些是必要的更改:

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());
    }
}

设置项目(或测试项目),在使用ant构建时,使用此类作为AndroidManifest.xml中的检测测试运行器:

<instrumentation
    android:name="my.package.CustomInstrumentationTestRunner"
    android:targetPackage="my.target.package" />
使用gradle构建时

或其build.gradle

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

如果您有其他instrumentation个条目,您可以在它们之间切换on the command line或在IDE运行配置中选择一个。

答案 3 :(得分:3)

我有一个Android库项目的问题,但不适用于应用程序项目!如上所述设置系统属性“dexmaker.dexcache”解决了这个问题。 我正在运行Android 4.3 Nexus 4设备,使用19.0.3工具构建,目标api 19, 我的依赖:

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

答案 4 :(得分:3)

dexmaker 项目似乎已从Google Code移至GitHub

the maven central repository中,2014年3月和2014年12月发布了版本1.1和1.2。

我已经验证了这个“dexcache == null”问题仍然存在于版本1.2中 - 但仅限于某些设备。例如,带有Android 5.0的Galaxy S5有问题,带有Android 4.4.2的Galaxy S4没有。

我克隆了GitHub存储库(last commit March 12th 2015 - ca74669),然后在本地运行,问题已得到修复(历史记录中也有提交备份)。所以一旦有1.3版本发布,希望这个问题不复存在!

其他人想要运行1.3-SNAPSHOT的本地副本,这就是我的做法(在Mac上,但其他平台也应该有效,你需要 mvn adb 路径 dx 路径

  1. git clone https://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. 然后更改app/build.gradle中的版本:androidTestCompile 'com.google.dexmaker:dexmaker:1.3-SNAPSHOT'
    • pom.xml如果使用maven构建,或者如果您使用的是libs/dexmaker.jar,则覆盖~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar
  6. 此外,仅供参考,original issue report也适用于Google Code上的相同问题。

答案 5 :(得分:2)

您可以将mockito核心添加为依赖项。然后,该错误将不会发生,您将不需要解决方法。

dependencies {
   ... 
   testCompile 'org.mockito:mockito-core:1.10.19'
}

答案 6 :(得分:0)

在对test文件夹中的资源和文件夹进行操作时,我观察到此问题。实际上,仅重新启动Android Studio即可。简单,但是有效。