当我运行以下代码时:
public class ActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
....
public void testCanCreateMockito() {
List mockedList = Mockito.mock(List.class);
}
}
我得到以下例外情况:
java.lang.ExceptionInInitializerError
at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
at org.mockito.Mockito.mock(Mockito.java:1285)
at org.mockito.Mockito.mock(Mockito.java:1163)
at com.acesounderglass.hungertracker.ActivityTest.testCanCreateMockito(ActivityTest.java:60)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
Caused by: org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105)
at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70)
... 23 more
Caused by: java.lang.reflect.InvocationTargetException
at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)
... 28 more
Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
at java.lang.ClassLoader.defineClass(ClassLoader.java:300)
... 32 more
这适用于任何类,List只是一个简单的例子。我的gradle依赖是:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.0'
androidTestCompile "org.mockito:mockito-core:1.+"
androidTestCompile files('libs/dexmaker-mockito-1.0.jar')
androidTestCompile files('libs/dexmaker-1.0.jar')
}
我已将gradle升级到1.1,尝试使用实验单元测试功能而不是,似乎没有任何区别。发生了什么事?
答案 0 :(得分:89)
当我错过了两个dexmaker依赖项时,我收到了这个错误。
将这些行添加到app / gradle.build文件对我有用。
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
我也在使用Android Studio,并且发现在更改依赖项后重新启动AS是一个好主意。
答案 1 :(得分:9)
对我而言,这最终奏效了:
androidTestCompile "org.mockito:mockito-core:1.10.19"
androidTestCompile "com.crittercism.dexmaker:dexmaker:1.4"
androidTestCompile "com.crittercism.dexmaker:dexmaker-mockito:1.4"
androidTestCompile "com.crittercism.dexmaker:dexmaker-dx:1.4"
答案 2 :(得分:3)
我得到这个是因为我使用proguard进行调试构建,因为65K方法限制(是的,我需要减少依赖项的数量),这对我造成了这个错误。
我在我的(debug)proguard配置中添加了这个来解决它:
### Keep Mockito
-keep class org.mockito.** { *; }
-keep interface org.mockito.** { *; }
-keep class com.google.dexmaker.** { *; }
-keep interface com.google.dexmaker.** { *; }
不确定如果我真的需要所有这四条线,但这就行了。
答案 3 :(得分:1)
我遇到了与EasyMock相同的错误,并最终将其追溯到缺少dexmaker。我用以下依赖项解决了它:
androidTestCompile "com.google.dexmaker:dexmaker:1.2"
这可能也适用于mockito
答案 4 :(得分:1)
如果你没有使用年级建立你的APK!
如果您不使用gradle构建应用程序(不幸的是,我的团队没有),那么上述解决方案可能对您不起作用。在解决问题之前,让我先解释一下dexmaker-mockito的工作原理。
<强>动机强>
Mockito是Java的一个模拟框架,它与cglib一起打包创建了Bytecode模拟,这就是Instrumentation测试之外的Mockito / Junit的工作原理。但是如果你试图在Android仪器测试中运行Mockito,那么Bytecode模拟是不够的,你需要Mockito可以加载到ART / Dalvik可以理解的Dex类加载器的模拟,这就是Dexmaker的用武之地.Dexmaker有一个Mockito“插件“这允许Mockito动态切换到使用它来创建Dex模拟。
如何知道切换?
dexmaker-mockito jar有一个名为mockito-extensions/org.mockito.plugins.MockMaker
的顶级文件夹,其中包含一个完全限定的名称com.google.dexmaker.mockito.DexmakerMockMaker
。当这个jar与APK一起打包时,这个顶级文件夹可以作为“类加载器资源”包含在内。
Mockito用来抽象Mocking层的类称为MockUtil,并且静态地,它通过检查类加载器中通过其{{3}启动的这些资源来确定它应该使用哪个MockMaker子类。 }}。如果可以找到来自dexmaker-mockito的资源,那么com.google.dexmaker.mockito.DexmakerMockMaker
将被实例化并用作MockMaker,但如果不是,则Mockito默认使用CGLib,这在Android的DVM中是不兼容的。
<强>问题强>
根据您构建APK的方式,您可能会剥离该类加载器资源并导致Mockito无法动态切换到使用Dexmaker。
<强>修正强>
首先,包括dexmaker要求的罐子:mockito 1.9.5 +,junit,dexmaker-mockito 1.0+和dexmaker 1.0+,然后简单地反射切换哪个MockMaker Mockito将手动使用。这是安全的,因为如果它在DVM中运行,使用默认的CGLib MockMaker将无法工作,因为它会产生Bytecode模拟。
static {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
Enumeration<URL> resources = loader.getResources("mockito-extensions/org.mockito.plugins.MockMaker");
if (resources == null || !resources.hasMoreElements()) {
LOGGER.info("Replacing Mockito mockMaker because the classloader resources were not present.");
Field field = MockUtil.class.getDeclaredField("mockMaker");
Class<?> pluginClass = loader.loadClass("com.google.dexmaker.mockito.DexmakerMockMaker");
Object plugin = pluginClass.newInstance();
field.setAccessible(true);
field.set(null, plugin);
} else {
LOGGER.info("Mockito class loader resources present");
}
} catch (Throwable e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
throw new AssertionError("Unable to replace mockMaker to be the DexmakerMockMaker", e);
} else {
e.printStackTrace();
throw new AssertionError("Unable to replace mockMaker to be the DexmakerMockMaker");
}
}
}
并且一定要添加它,因为dexmaker需要知道在哪里输出它的Dex模拟。
System.setProperty("dexmaker.dexcache", "/sdcard/");
答案 5 :(得分:1)
我偶然发现了相同的错误,可以通过使用
使其正常工作 androidTestImplementation 'org.mockito:mockito-android:2.18.3'
在我的 build.gradle 中。
我以前犯过错误,仅导入'org.mockito:mockito-core:2.18.3'
。
答案 6 :(得分:0)
User23的答案接近于对我有用的解决方案。
根据official documentation,您必须在Android应用中激活Mockito以下内容:
将以下依赖项添加到build.gradle中:
androidTestCompile "org.mockito:mockito-core:1.10.19"
androidTestCompile fileTree(dir: 'libs', include: ['dexmaker-1.4.jar'])
androidTestCompile fileTree(dir: 'libs', include: ['dexmaker-mockito-1.4.jar'])