37

我正在尝试在我的 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)

知道如何解决吗?

4

7 回答 7

33

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

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

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

于 2014-03-14T10:37:00.260 回答
10

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

我相信这是可行的,因为默认情况下 mockito 尝试使用应用程序缓存目录,但我从未运行过活动,所以我怀疑该目录从未由操作系统创建

于 2012-10-01T17:27:16.717 回答
8

因此,问题在于 Dexmaker 无法在 Android >= 4.3 上找到缓存路径,正如其他人所提到的以及此 dexmaker 问题中所述。

我在自定义检测测试运行器中而不是在每个测试(或它们的超类)中实现解决方法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());
    }
}

并设置您的项目(或测试项目)以在AndroidManifest.xml使用 ant 构建时将此类用作其检测的测试运行器:

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

或者build.gradle在使用 gradle 构建时:

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

如果您有其他条目,您可以在命令行instrumentation中切换它们,也可以在 IDE 运行配置中选择一个。

于 2014-05-23T08:54:08.617 回答
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"
于 2014-06-01T15:17:45.163 回答
3

看起来dexmaker项目已经从Google Code转移到了GitHub

maven 中央存储库中有 1.1 和 1.2 版本,分别于 2014 年 3 月和 2014 年 12 月发布。

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

我克隆了 GitHub 存储库(最后一次提交 2015 年 3 月 12 日 - ca74669),并在本地运行,问题已得到解决(历史记录中也有提交支持此问题)。所以一旦有 1.3 版本,希望这个问题永远消失!

其他任何想要运行 1.3-SNAPSHOT 的本地副本的人,我都是这样做的(在 Mac 上,但其他平台也应该可以工作,你需要PATH上的mvnadbdx):

  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. 然后更改版本app/build.gradleandroidTestCompile 'com.google.dexmaker:dexmaker:1.3-SNAPSHOT'
    • 或者pom.xml如果使用 maven 构建,或者如果你使用 eclipse/antlibs/dexmaker.jar覆盖你~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar

此外,仅供参考,Google Code 上同一问题的原始问题报告也是如此。

于 2015-03-24T23:26:07.400 回答
2

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

dependencies {
   ... 
   testCompile 'org.mockito:mockito-core:1.10.19'
}
于 2016-11-07T18:04:52.470 回答
0

我在对文件夹内的资源和文件夹进行操作时观察到了这个问题test。实际上只是重新启动 Android Studio 有帮助。简单,但有效。

于 2019-12-16T10:10:33.290 回答