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上的mvn , adb和dx ):
-
git clone
https://github.com/crittercism/dexmaker.git -
cd dexmaker
-
mvn install -Dmaven.test.skip=true
-
cp -R ~/.m2/repository/com/google/dexmaker $ANDROID_HOME/extras/android/m2repository/com/google
- 然后在
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
- 如果使用maven构build,或者使用
此外,FYI也是Google Code上同一问题的原始问题报告 。
您可以将mockito核心添加为依赖项。 那么,这个错误不会发生,你不需要一个解决方法。
dependencies { ... testCompile 'org.mockito:mockito-core:1.10.19' }