Dagger 不为 /test class 生成组件

Dagger not generating components for /test class

我正在按照此处的指南进行操作:https://github.com/ecgreb/dagger-2-testing-demo

我的 app/src/main 中有以下设置(省略了注入和 @Provides 代码):

public class FlingyApplication extends Application {
    @Singleton
    @Component(modules = { FlingyModule.class })
    public interface FlingyComponent
}

@Module
public class FlingyModule

在app/src/test中:

public class TestFlingyApplication extends Application {
    @Singleton
    @Component(modules = { TestFlingyModule.class })
    public interface TestFlingyComponent extends FlingyComponent
}

@Module
public class TestFlingyModule

到目前为止,它与示例github 几乎相同。当 dagger 为 src/main 中的组件构建器生成代码时,它们会正确生成。但是,Dagger 不会为 src/test.

中的组件生成器生成代码

我的主要build.gradle:

dependencies {
    classpath 'com.android.tools.build:gradle:2.1.0-alpha3'

    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.5.1'
}

我的app/build.gradle

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'


android {
    # There is obviously more in here, but this is the custom part:
    packagingOptions {
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
}

dependencies {
    compile 'com.squareup:otto:1.3.8'
    compile 'com.android.support:cardview-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.jakewharton:butterknife:7.0.1'

    compile 'com.google.dagger:dagger:2.0.1'
    apt 'com.google.dagger:dagger-compiler:2.0.1'
    compile 'javax.annotation:javax.annotation-api:1.2'

    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'io.reactivex:rxjava:1.1.0'

    testCompile 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    testCompile 'junit:junit:4.12'
    testCompile 'org.robolectric:robolectric:3.0'
    testCompile 'org.mockito:mockito-core:1.10.19'
}

所以当我构建时,我得到 DaggerFlingyApplication_FlingyComponent class,但没有 DaggerTestFlingyApplication_TestFlingyComponent

我注意到的一件有趣的事是,如果我换行:

apt 'com.google.dagger:dagger-compiler:2.0.1'
# TO
compile 'com.google.dagger:dagger-compiler:2.0.1'

我在 运行 ./gradlew compileDebugUnitTestSources 时看到以下内容:

:app:compileDebugJavaWithJavac
Note: /app/build/generated/source/apt/debug/com/jy/flingy/DaggerFlingyApplication_FlingyComponent.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:app:preDebugUnitTestBuild UP-TO-DATE
:app:prepareDebugUnitTestDependencies
:app:compileDebugUnitTestJavaWithJavac
Note: /app/build/intermediates/classes/test/debug/com/jy/flingy/DaggerTestFlingyApplication_TestFlingyComponent.java uses unchecked or unsafe operations.

我不知道为什么它会生成中间体,我假设我需要 build.gradle 文件来使用 apt 而不是 compile,但我似乎做不到弄清楚如何让它工作。我知道这是绝对可能的。

您需要将以下内容添加到您的 build.gradle 文件中以进行仪器测试:

androidTestApt 'com.google.dagger:dagger-compiler:<version>'

或者对于 JUnit 测试:

testApt 'com.google.dagger:dagger-compiler:<version>'

这是为您的测试组件生成 Dagger 代码所必需的。


编辑:

如果您使用的是 jack 工具链,请添加以下内容 对于 android 测试:

androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:<version>'

对于 JUnit 测试:

testAnnotationProcessor 'com.google.dagger:dagger-compiler:<version>'

编辑:

如果您将 kotlin-kapt 用于 Kotlin 代码,请使用以下代码:

kaptAndroidTest 'com.google.dagger:dagger-compiler:<version>'

或者对于 JUnit 测试:

kaptTest 'com.google.dagger:dagger-compiler:<version>'

查看 this link 了解更多信息。

只是对上面的答案添加一点,因为最近有一些更改。

从 Android Gradle 插件版本 2.2 及以上你 将不再使用 testApt.

所以从现在开始你只需要把这个放在 build.gradle:

testAnnotationProcessor 'com.google.dagger:dagger-compiler:<version>'

但不仅如此,我来这里的目的是:如果您需要gradle为您生成 DaggerComponent类您将不得不做一些额外的工作。

打开我们的 build.gradle 文件并在 android 部分之后写下:

android.applicationVariants.all { variant ->
    if (variant.buildType.name == "debug") {
        def aptOutputDir = new File(buildDir, "generated/source/apt/${variant.unitTestVariant.dirName}")
        variant.unitTestVariant.addJavaSourceFoldersToModel(aptOutputDir)
        assembleDebug.finalizedBy('assembleDebugUnitTest')
    }
}

这将创建目录 build/generated/source/apt/test/ 作为 Java 类 收件人,最后一部分将触发 "assembleDebugUnitTest" 任务,最终将在中创建那些 Dagger2 组件刚刚创建的文件夹。

请注意,此脚本仅针对 "debug" 变体触发,并使用 "assembleDebug" 任务利用该构建变体。如果出于某种原因您需要在其他变体中使用它,只需稍微调整一下即可。

我不知道为什么 Dagger2 不自动执行此操作,但是嘿,我不是专业人士。

对于 Android Studio 3 和 dagger 2.13,需要已经提到的注释处理器:

testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.13'

但也不要忘记为 androidTest 下的仪器测试执行此操作:

androidTestAnnotationProcessor'com.google.dagger:dagger-compiler:2.13'

您可能会觉得仅此一项是行不通的,因为未生成 DaggerXYZ 类。几个小时后,我发现测试源生成仅在执行测试时触发。如果您从 Android Studio 启动 testandroidTest,则应触发源代码生成。

如果您需要手动触发gradle:

gradlew <moduledirectory>:compile<Flavor>DebugAndroidTestSources
gradlew <moduledirectory>:compile<Flavor>DebugTestSources

如果您 运行 在不同的构建类型中进行测试,请替换 Debug

注:

如果您使用 multiDexEnable = true,您可能会遇到错误:

Test running failed: Instrumentation run failed due to 'java.lang.IncompatibleClassChangeError'

在这种情况下使用不同的 运行ner:

android {

  defaultConfig {
    multiDexEnabled true
    testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"

如果您使用的是 kotlin,请使用“kaptAndroidTest”为 build.gradle 文件中的 android 测试生成 Dagger 组件。

如果您为 dagger 依赖添加了 kaptAndroidTest,但在重建项目时仍未获取测试组件,请尝试 运行 assembleAndroidTest。

添加到上述解决方案并为 dagger 添加 testKapt 和 androidTestKapt,我遇到的问题是我的模块和组件由于缺少导入而导致导入错误

例如

 import android.support.test.espresso.core.deps.dagger.Module
 import android.support.test.espresso.core.deps.dagger.Module

而不是

import dagger.Module
import dagger.Provides

希望对您有所帮助

您好,即使在添加了所有 gradle 依赖项和注释之后,如果它仍然不起作用,那么您需要为此 运行 组装 AndroidTest gradle 脚本。 只需制作一个空的测试用例并 运行 它。它会为你完成这项工作。 干杯

我从命令行 运行 ./gradlew build 获得了有关缺少 Provides 方法的信息,Android Studio 没有告诉我。