Dagger 2 生成的测试组件无法识别

Dagger 2 generated test component not recognized

我希望这只是我在这里做错的事情。我正在尝试使用 Dagger 2.0 为我的 JUnit 测试注入依赖项(不是 Espresso 测试,只是纯 JUnit)。所以,我有一个 'main' java 模块和一个 'test' java 模块。在主模块中,我有一个 Dagger 模块和一个组件:

@Module
public class MainModule {
    @Provides
    public Widget provideWidget() {
        return new ConcreteWidget();
    }
}

...

@Component (modules = MainModule.class)
public interface MainComponent {
    void inject(WidgetConsumer consumer);
}

在我的测试模块中,我有以下内容:

@Module
public class TestModule {
    @Provides public Widget provideWidget() {
        return new Widget() {
            @Override
            public void doThing() {
                int y = 6;
                y ++;
            }
        };
    }
}

...

@Component(modules = TestModule.class)
public interface TestComponent extends MainComponent{
}

我的 build.gradle 具有如下所示的依赖项:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    testCompile 'junit:junit:4.12'

    compile 'com.google.dagger:dagger:2.9'
    testCompile 'com.google.dagger:dagger:2.9'

    annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
    testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.9'
}

无论出于何种原因,Dagger 都会生成 DaggerMainComponent,但拒绝生成 DaggerTestComponent。我构建时 gradle 输出中似乎没有错误。

事情是这样的...我认为注释处理器是 运行,但不知何故 android gradle 插件无法在编译期间提取那些生成的源代码。我检查了 app/build/generated/source/apt/test/ 目录并在其中找到了 DaggerTestComponent.java,但由于某种原因,它没有作为依赖项导入。

有什么想法吗? Here is a link to a test project showing my issue

我找到了一个解决方法,以防万一以后有人遇到这个问题。 android gradle 插件中的 testAnnotationProcessor 命令似乎不适用于测试模块(可能是其实现中的错误?)。所以你可以写 testAnnotationProcessor 并且你的 build.gradle 会编译但它似乎不能正常工作。

解决方法是回退到 Hugo Visser (android-apt) 的旧第三方注释处理插件。

为此,请将以下内容添加到您的主要 build.gradle 中的构建脚本依赖项中:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0-rc1'

        // ADD THIS LINE HERE vvv
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

然后,在您的个人模块 build.gradle 中,在顶部添加以下行:

apply plugin: 'com.android.library'

// ADD THIS LINE HERE vvv
apply plugin: 'com.neenbedankt.android-apt'

最后,不用testAnnotationProcessorannotationProcessor,只用apttestApt:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'

    compile 'com.google.dagger:dagger:2.9'
    // USE apt INSTEAD OF annotationProcessor HERE vvv
    apt 'com.google.dagger:dagger-compiler:2.9'

    testCompile 'com.google.dagger:dagger:2.9'
    // USE testApt INSTEAD OF testAnnotationProcessor HERE vvv
    testApt 'com.google.dagger:dagger-compiler:2.9'

    testCompile 'junit:junit:4.12'
}

请注意,您必须使用 1.8 版本的 android-apt,因为 1.4 版本未随 testApt command/function/whatever.

一起提供

android DSL 之后将此添加到 build.gradle

android {
    ...
}

android.applicationVariants.all {
    def aptOutputDir = new File(buildDir, "generated/source/apt/${it.unitTestVariant.dirName}")
    it.unitTestVariant.addJavaSourceFoldersToModel(aptOutputDir)
}

之后,您的测试组件将被识别。

对于 Kotlin,将 generated/source/apt/... 替换为 generated/source/kapt/...

跟踪器中有an issue raised与此有关。

取决于您的测试类型:

  • src/test
  • 的 build.gradle 文件的依赖项中插入 testAnnotationProcessor "com.google.dagger:dagger-compiler:2.x"

  • src/androidTest
  • 的 build.gradle 文件的依赖项中插入 androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.x"