java - RoboGuice android 注入(inject)模块在测试中不起作用

标签 java android unit-testing robolectric roboguice

我创建了一个 TestModule 类来注入(inject)测试实现类,但它失败并出现 classCastException。

我正在使用 Robolectric 2.4。

这是我的自定义 TestApplication,它是通过自定义 robolectric 运行器创建的

public class AppApplicationTest extends MyApplication {

@Override
protected void attachBaseContext(Context base) {
    configureModuleInjection();
    System.out.println(this.getClass().getSimpleName() + " attached and initialised AppApplicationTest ");

    try {
        MultiDex.install(base);
        super.attachBaseContext(base);
    } catch (RuntimeException ignored) {
        // Multidex support doesn't play well with Robolectric yet
        System.out.println(this.getClass().getSimpleName() + " runtime exception = " + ignored.toString());
    }
}

private void configureModuleInjection() {
//fails below with classCastException
    RoboGuice.getOrCreateBaseApplicationInjector(this,
            RoboGuice.DEFAULT_STAGE,
            RoboGuice.newDefaultRoboModule(this),
            new TestModule());
}
}

这是我的自定义 RobolectricTestRunner

    public class MyRoboTestRunner extends RobolectricTestRunner {

    ....

    @Override
    protected Class<? extends TestLifecycle> getTestLifecycleClass() {
        return ApplicationTest.class;
    }

    public  static class ApplicationTest extends DefaultTestLifecycle{
        @Override
        public Application createApplication(Method method, AndroidManifest appManifest, Config config) {
            return new AppApplicationTest();
        }
    }

    @Override
    protected ClassLoader createRobolectricClassLoader(Setup setup, SdkConfig sdkConfig) {
        return super.createRobolectricClassLoader(new ExtraShadows(setup), sdkConfig);
    }

    class ExtraShadows extends Setup{
        private  Setup setup;

        public ExtraShadows(Setup setup) {
            this.setup = setup;
        }

        @Override
        public boolean shouldInstrument(ClassInfo classInfo) {
            boolean shouldInstrument = setup.shouldInstrument(classInfo);
            return shouldInstrument || classInfo.getName().equals(MultiDex.class.getName());
        }
    }
}

这是完整的堆栈跟踪错误

    WARNING: no system properties value for ro.build.date.utc
java.lang.ClassNotFoundException: AnnotationDatabaseImpl
    at org.robolectric.bytecode.AsmInstrumentingClassLoader.getByteCode(AsmInstrumentingClassLoader.java:172)
    at org.robolectric.bytecode.AsmInstrumentingClassLoader.findClass(AsmInstrumentingClassLoader.java:126)
    at org.robolectric.bytecode.AsmInstrumentingClassLoader.loadClass(AsmInstrumentingClassLoader.java:98)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:191)
    at com.google.inject.AnnotationDatabaseFinder.getAnnotationDatabaseInstance(AnnotationDatabaseFinder.java:73)
    at com.google.inject.AnnotationDatabaseFinder.<init>(AnnotationDatabaseFinder.java:36)
    at com.google.inject.Guice.setAnnotationDatabasePackageNames(Guice.java:133)
    at roboguice.RoboGuice.initializeAnnotationDatabaseFinderAndHierarchyTraversalFilterFactory(RoboGuice.java:288)
    at roboguice.RoboGuice.getOrCreateBaseApplicationInjector(RoboGuice.java:113)
    at com.jr.AppApplicationTest.configureModuleInjection(AppApplicationTest.java:33)
    at com.jr.AppApplicationTest.attachBaseContext(AppApplicationTest.java:20)
    at android.app.Application.$$robo$$Application_0b64_attach(Application.java:181)
    at android.app.Application.attach(Application.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.robolectric.internal.ReflectionHelpers$3.run(ReflectionHelpers.java:64)
    at org.robolectric.internal.ReflectionHelpers.traverseClassHierarchy(ReflectionHelpers.java:114)
    at org.robolectric.internal.ReflectionHelpers.callInstanceMethodReflectively(ReflectionHelpers.java:59)
    at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:119)
    at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:440)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:222)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
java.lang.IllegalStateException: Unable to use annotation database(s)
    at roboguice.RoboGuice.initializeAnnotationDatabaseFinderAndHierarchyTraversalFilterFactory(RoboGuice.java:292)
    at roboguice.RoboGuice.getOrCreateBaseApplicationInjector(RoboGuice.java:113)
    at com.jr.AppApplicationTest.configureModuleInjection(AppApplicationTest.java:33)
    at com.jr.AppApplicationTest.attachBaseContext(AppApplicationTest.java:20)
    at android.app.Application.attach(Application.java:181)
    at org.robolectric.internal.ReflectionHelpers$3.run(ReflectionHelpers.java:64)
    at org.robolectric.internal.ReflectionHelpers.traverseClassHierarchy(ReflectionHelpers.java:114)
    at org.robolectric.internal.ReflectionHelpers.callInstanceMethodReflectively(ReflectionHelpers.java:59)
    at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:119)
    at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:440)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:222)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

最佳答案

因为这一行 java.lang.IllegalStateException:无法使用注释数据库

你可以尝试使用RoboGuice.setUseAnnotationDatabases(false);

private void configureModuleInjection() {

    RoboGuice.setUseAnnotationDatabases(false);

    RoboGuice.getOrCreateBaseApplicationInjector(this,
        RoboGuice.DEFAULT_STAGE,
        RoboGuice.newDefaultRoboModule(this),
        new TestModule());

}

关于java - RoboGuice android 注入(inject)模块在测试中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41632105/

相关文章:

java - Javacc 终端的奇怪错误

java - 在不同平台上通过java用python打开终端窗口

java - PrintStream 类型中的方法 printf(String, Object...) 不适用于参数 (String, void)

c# - Visual Studio 2008 Pro 中的单元测试 float 操作

objective-c - 为什么我的对象的弱委托(delegate)属性在我的单元测试中为 nil?

java - 通过 JMS 接收 Java 对象

android - 面对 Dex 65K 方法限制错误

java - 无法将 Java 类型转换为 Yail 类型

java - Android Studio 中的 OnClickListener

unit-testing - 如何对事件是否执行 segue 进行单元测试