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

我收到这个exception:

 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) 

任何想法如何解决它?

从@ rjath评论@ MrChaz的回答,这对我更好:

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

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

我已经设法拼凑出一个似乎正在为我工​​作的修复。 清单我添加了读写外部存储。 为了testing,我添加了System.setProperty("dexmaker.dexcache", "/sdcard"); 到testing。 对模拟器的图像,我添加了一个SD卡。

我相信这是可行的,因为默认情况下mockito会尝试使用应用程序caching目录,但我从不运行一个活动,所以我怀疑这个目录永远不会被操作系统创build

所以问题在于Dexmaker无法像其他人提到的那样在Android 4.3以上版本中findcachingpath。

我在一个自定义的testing运行器中,而不是在每个testing(或他们的超类) setUp()实现了这个解决方法,因为它感觉有点不好玩(它只是在一个地方 – 而不是在每个子类中inheritance)更灵活。 为了文档的缘故,这些是必要的改变:

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

并build立你的项目(或testing项目)使用这个类作为testing运行器在AndroidManifest.xml使用ant进行构build时:

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

或者使用build.gradle构build时的build.gradle:

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

如果您有其他instrumentation条目,则可以在命令行中切换它们,也可以在IDE运行configuration中select一个条目。

我有这个问题的Android库项目,但不适用于应用程序项目! 如上所述设置系统属性“dexmaker.dexcache”解决了这个问题。 我正在运行Android 4.3 Nexus 4设备,使用19.0.3工具构build,目标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" 

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

在maven中央仓库中,有2014年3月和2014年12月发布的版本1.1和1.2。

我已经validation了这个“dexcache == null”问题在1.2版本中仍然存在 – 但只在某些设备上。 例如,Android 5.0的Galaxy S5有问题,Android 4.4.2的Galaxy S4没有。

我克隆了GitHub存储库( 最后一次提交2015年3月12日 – ca74669 ),并在本地运行,问题已修复(历史logging中还提交了此提交)。 所以一旦有了1.3版本,希望这个问题没有好转!

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

  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'
    • 如果使用maven构build,或者使用pom.xml ,或者使用~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar覆盖libs/dexmaker.jar /ant

此外,FYI也是Google Code上同一问题的原始问题报告 。

您可以将mockito核心添加为依赖项。 那么,这个错误不会发生,你不需要一个解决方法。

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