【问题标题】:Android instrumentation tests with Mockito [duplicate]使用 Mockito 进行 Android 仪器测试 [重复]
【发布时间】:2016-04-22 22:42:32
【问题描述】:

我正在尝试将 Mockito 框架与 android 仪器测试一起使用,但我无法正确初始化它。我有以下测试类:

class MainKontorTest extends ActivityInstrumentationTestCase2<MainActivity> {

    @Mock Dependency bar;

    @Override
    public void setUp() {
        super.setUp();
        MockitoAnnotations.initMocks(this);
    }

    public void testSomething() {
        Foo foo = new Foo(bar);
    }
}

当我尝试运行此测试时,我收到以下错误和堆栈跟踪:

java.lang.ExceptionInInitializerError 在 org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95) 在 org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57) 在 org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49) 在 org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24) 在 org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) 在 org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) 在 org.mockito.Mockito.mock(Mockito.java:1285) 在 org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33) 在 org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16) 在 org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43) 在 org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66) 在 org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71) 在 org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55) 在 org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108) 在 org.arkadiy.moduledelegationsample.ui.main.MainKontorTest.setUp(MainKontorTest.java:20) 在 junit.framework.TestCase.runBare(TestCase.java:132) 在 junit.framework.TestResult$1.protect(TestResult.java:115) 在 android.support.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:77) 在 junit.framework.TestResult.run(TestResult.java:118) 在 android.support.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:55) 在 junit.framework.TestCase.run(TestCase.java:124) 在 android.support.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:63) 在 junit.framework.TestSuite.runTest(TestSuite.java:243) 在 junit.framework.TestSuite.run(TestSuite.java:238) 在 android.support.test.internal.runner.junit3.DelegatingTestSuite.run(DelegatingTestSuite.java:103) 在 android.support.test.internal.runner.junit3.AndroidTestSuite.run(AndroidTestSuite.java:69) 在 android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90) 在 org.junit.runners.Suite.runChild(Suite.java:128) 在 org.junit.runners.Suite.runChild(Suite.java:27) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:115) 在 android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54) 在 android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:240) 在 android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1869) 引起:org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null 在 org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238) 在 org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145) 在 org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117) 在 org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109) 在 org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105) 在 org.mockito.cglib.proxy.Enhancer.(Enhancer.java:70) ... 40 更多 引起:java.lang.reflect.InvocationTargetException 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385) 在 org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220) ... 45 更多 引起:java.lang.UnsupportedOperationException:无法加载此类文件 在 java.lang.ClassLoader.defineClass(ClassLoader.java:300) ... 49 更多

如何将 Mockito 与 Instrumentation 测试一起使用?我曾尝试将 Mockito 与较新的 Rule api 一起使用,但错误是相同的。

【问题讨论】:

标签: java android unit-testing junit mockito


【解决方案1】:

Mockito 创建的模拟是生成的类文件;但是,Mockito 是为在 JVM 中使用而设计的,因此它开箱即用地使用 cglib 生成 .class 文件。 Android Instrumentation 测试用例在设备或模拟器上运行,因此它们需要 Dalvik .dex 文件。

您需要确保在类路径中包含DexMakerdexmaker-mockito Maven 项目似乎是正确的,尽管它依赖于 Mockito 1.10.5,在这一点上落后了几个版本。

附带说明,除非您使用 Android Testing Support Library,否则您将需要使用 JUnit3 语义。您将无法使用@Rule 字段或自定义测试运行器;您还需要覆盖 setUptearDown(而不是 @Before@After 注释)并将您的测试命名为 testFooBar(而不是 @Test 注释)。

【讨论】:

  • 有没有例子说明使用什么注解,如何定义类,测试方法等?
  • 如果您不使用 gradle 构建 APK,这可能不适合您。有关更多信息,请参阅我在 stackoverflow.com/questions/29290795/… 上的回答
  • 为什么我们不能在 JUnit 4 中使用 @Rule 注释?
  • @Igor 你可以,但应该知道,Android 仪器测试(这是人们在这个问题中寻找 DexMaker 的主要原因)使用 JUnit 3 作为他们的内置库。 JUnit 4 和它的 @Rule 仅在 JVM/Robolectric 测试(不是这个问题)或通过我上面链接中的支持库提供。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 2017-02-25
相关资源
最近更新 更多