Dagger не генерирует компоненты для / тестового класса

Я следую руководству здесь: https://github.com/ecgreb/dagger-2-testing-demo

В моем приложении / 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'
}

Мое приложение / 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 класс, но не 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, но я не могу понять, как заставить это работать. Я знаю, что это абсолютно возможно.


person jyanks    schedule 26.03.2016    source источник
comment
В этой документации (google.github.io/dagger/testing.html) рекомендуется не используйте dagger для модульного тестирования ..   -  person Kishan B    schedule 24.04.2017
comment
Если у вас много зависимостей, это может указывать на то, что ваши модульные тесты тестируют более одного модуля. Тем не менее, Google не всегда знает лучше (ах!), И это довольно широкое их утверждение. Использование dagger в модульных тестах в конкретных случаях работает для нас, отсюда и этот вопрос.   -  person jyanks    schedule 24.04.2017
comment
stackoverflow.com/a/60352086/4694013   -  person Anoop M Maddasseri    schedule 22.02.2020


Ответы (8)


Вам необходимо добавить следующее в ваш 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>'

Дополнительную информацию можно найти по этой ссылке.

person Abdullah    schedule 26.03.2016
comment
Даже если тесты находятся в / test, а не в / androidTest? - person jyanks; 26.03.2016
comment
Вы пишете инструментальный тест, который должен быть в androidTest. Если вы пишете тест JUnit, вы можете использовать testApt. - person Abdullah; 26.03.2016
comment
Получаю следующее: Error:(55, 0) Gradle DSL method not found: 'testApt()' - person jyanks; 26.03.2016
comment
Мне пришлось обновить apt до 1.7 + ... classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8', чтобы testApt работал - person jyanks; 26.03.2016
comment
Спасибо! Я искал ответ два дня :) - person gc986; 17.11.2016
comment
Я пробовал использовать этот вариант testAnnotationProcessor, но класс не создается. Вы знаете, есть ли проблемы с этим подходом? - person Leandro Ocampo; 01.04.2017
comment
Эта опция доступна только для jack цепочки инструментов. - person Abdullah; 01.04.2017
comment
Зависимости процессоров Jack не работают с процессорами в каталоге / test. Я переключился на apt, и он отлично работает. Так что, если вам нужна эта функциональность, откажитесь от Джека и используйте apt. - person Jason Robinson; 07.07.2017
comment
Вы знаете, поддерживается ли testAnnotationProcessor для Kotlin? Насколько я знаю просто поддерживаю kapt - person Daniel Gomez Rico; 25.07.2017
comment
kotlinlang.org/docs/reference/kapt.html По этой ссылке вы можете использовать kaptTest и kaptAndroidTest при использованииkapt. - person Abdullah; 26.07.2017
comment
Не забудьте выполнить тесты или запустить assembleAndroidTest, чтобы действительно увидеть, что класс зависимостей DaggerMyComponent разрешен, просто rebuild не будет генерировать классы из dagger. - person jamesbluecrow; 01.12.2017
comment
Спасибо! Это очень полезно - person Xi Wei; 14.10.2018
comment
Спасибо, сэр. Очень тщательно и очень полезно. - person Aaron Dancygier; 25.10.2018
comment
Сэкономил мне много времени. Спасибо - person CodeCameo; 14.08.2020

Для Android Studio 3 и dagger 2.13 необходимы уже упомянутые обработчики аннотаций:

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

Но также не забудьте сделать это для инструментального теста под androidTest:

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

У вас может сложиться впечатление, что это само по себе не работает, потому что классы DaggerXYZ не генерируются. Спустя несколько часов я обнаружил, что генерация тестового источника запускается только при выполнении тестов. Если вы запустите test или androidTest из Android Studio, должна запуститься генерация исходного кода.

Если вам нужен этот более ранний триггер вручную:

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

Замените Debug, если вы запускаете тест в сборке другого типа.

Примечание.

Если вы используете multiDexEnable = true, вы можете получить сообщение об ошибке:

Ошибка выполнения теста: сбой при запуске инструментария из-за ошибки 'java.lang.IncompatibleClassChangeError'

В этом случае используйте другой бегун:

android {

  defaultConfig {
    multiDexEnabled true
    testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
person k_o_    schedule 11.12.2017
comment
Да, вам нужно запустить некоторые тесты, и тогда Dagger сгенерирует тестовые классы (компоненты) кинжала +1 - person Stoycho Andreev; 01.10.2018
comment
Я всегда думал, что rebuild проходит через весь проект, но, очевидно, нет. Спасибо чувак. - person Viacheslav; 20.02.2019
comment
androidTestAnnotationProcessor - это то, что я искал, спасибо! - person Johan Lund; 29.01.2021

Просто чтобы добавить немного к приведенному выше ответу, поскольку в последнее время были внесены некоторые изменения.

Начиная с версии 2.2 плагина Android Gradle и выше, вы больше не будете использовать 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 / created / source / apt / test / в качестве получателя классов Java, а последняя часть вызовет задачу «assemblyDebugUnitTest», которая, наконец, создаст эти компоненты Dagger2 в только что созданной папке.

Обратите внимание, что этот сценарий запускается только для варианта «отладка» и использует преимущества этого варианта сборки с помощью задачи «AssemblyDebug». Если по какой-то причине он вам нужен в других вариантах, просто немного подправьте его.

Почему Dagger2 не делает это автоматически, мне непонятно, но я не профессионал.

person CarlosGoncalves    schedule 10.08.2017
comment
У меня работает, ты пропустил финал } - person Efi MK; 06.09.2017
comment
Мне понравился этот подход, потому что он не требует установки дополнительных библиотек Android. Поскольку я делаю TDD в отдельной библиотеке, я начал с android.libraryVariants.all - person Juan Mendez; 13.09.2017
comment
Фантастика. После нескольких часов поиска альтернативы testApt это помогло. Спасибо! - person saltandpepper; 19.09.2017
comment
@saltandpepper какие-либо проблемы, с которыми вы столкнулись с последней версией Gradle? - person Shishir Shetty; 27.04.2018
comment
Спасибо. Мне потребовалось 2 дня, чтобы исправить это. Kotlin + Dagger 2.19 + последний класс - person Andrii Kovalchuk; 08.11.2018

Если вы добавили kaptAndroidTest для зависимостей dagger и по-прежнему не получаете тестовые компоненты при пересборке проекта, попробуйте запустить сборкуAndroidTest.

person Murat    schedule 15.07.2018
comment
Я рекомендую этот ответ, потому что он помогает вам посмотреть, не что-то не так с вашим графиком зависимостей или другими вещами вне зависимости - person Oscar Josue Alvrez; 28.02.2019
comment
Ты спас мне день, братан, я надолго застрял в этом вопросе. - person Rizwan; 02.09.2019

Добавив к вышеуказанному решению и добавив testKapt и androidTestKapt для кинжала, у меня возникла проблема, заключающаяся в том, что мои модули и компоненты имели неправильный импорт из-за отсутствия импорта

e.g

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

вместо того

import dagger.Module
import dagger.Provides

Надеюсь это поможет

person youssefhassan    schedule 08.08.2018
comment
Сначала я пропустил это предложение, потому что был уверен, что это не может быть проблемой, но, потратив еще 20 минут на отладку, я действительно пошел и проверил импорт. По какой-то причине Android Studio автоматически импортировала версии эспрессо. - person Nicholas; 19.03.2019

Привет, даже после добавления всех зависимостей и аннотаций gradle, если он все еще не работает, вам нужно запустить для этого скрипт gradle buildAndroidTest. Просто создайте пустой тестовый пример и запустите его. Он сделает всю работу за вас. Ваше здоровье

person Ehtisham Shami    schedule 20.08.2019

Если вы используете kotlin, используйте «kaptAndroidTest», чтобы сгенерировать компонент Dagger для тестов Android в вашем файле build.gradle.

person Dalvinder Singh    schedule 10.06.2018

Я запустил ./gradlew build из командной строки и получил информацию об отсутствующем методе Provides, о котором Android Studio мне не сообщала.

person elliptic1    schedule 11.09.2020