Dagger no genera componentes para /clase de prueba

8 minutos de lectura

Estoy siguiendo la guía aquí: https://github.com/ecgreb/dagger-2-testing-demostración

Tengo la siguiente configuración en mi app/src/main (se omiten la inyección y el código @Provides):

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

@Module
public class FlingyModule

En aplicación/origen/prueba:

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

@Module
public class TestFlingyModule

Hasta ahora, es casi idéntico al ejemplo de github. Cuando dagger va a generar el código para los constructores de componentes en src/main, se generan correctamente. Sin embargo, Dagger no genera código para los constructores de componentes en src/test.

Mi build.gradle principal:

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

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

Mi aplicación/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'
}

Así que cuando construyo, obtengo el DaggerFlingyApplication_FlingyComponent clase, pero no la DaggerTestFlingyApplication_TestFlingyComponent

Algo interesante que noté es que si cambio la línea:

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

Veo lo siguiente cuando corro ./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.

No sé por qué se compila en intermedios y supongo que necesito el archivo build.gradle para usar apt en vez de compile, pero parece que no puedo averiguar cómo hacer que esto funcione. Sé que es absolutamente posible.

  • Esta documentación (google.github.io/dagger/testing.html) consejos para no usar daga para pruebas unitarias..

    – Kishan B.

    24 de abril de 2017 a las 4:40

  • Si tiene muchas dependencias, entonces podría indicar que sus pruebas unitarias prueban más de una sola unidad. Dicho esto, Google no siempre sabe lo que es mejor (¡jadeo!) y esa es una afirmación bastante amplia de su parte. Usar daga en pruebas unitarias en casos particulares funciona bien para nosotros, de ahí esta pregunta.

    – jyanks

    24 de abril de 2017 a las 15:44

  • stackoverflow.com/a/60352086/4694013

    – Anoop M Maddasseri

    22 de febrero de 2020 a las 12:18

avatar de usuario
Abdalá

Necesitas agregar lo siguiente a tu build.gradle archivo para prueba de instrumentación:

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

o para la prueba JUnit:

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

Esto es necesario para generar código Dagger para sus componentes de prueba.


EDITAR:

Si estás usando jack cadena de herramientas y luego agregue lo siguiente para la prueba de Android:

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

para pruebas JUnit:

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

EDITAR:

En caso de que esté usando kotlin-kapt para el código Kotlin use lo siguiente:

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

o para la prueba JUnit:

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

Controlar este enlace para más información.

  • me sale lo siguiente: Error:(55, 0) Gradle DSL method not found: 'testApt()'

    – jyanks

    26 de marzo de 2016 a las 13:35

  • Tuve que actualizar apt a 1.7+… classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' para hacer que testApt funcione

    – jyanks

    26 de marzo de 2016 a las 14:10


  • Probé con esta variante “testAnnotationProcessor” pero la clase no se genera. ¿Sabes si hay algún problema con este enfoque?

    –Leandro Ocampo

    31 de marzo de 2017 a las 21:38

  • Las dependencias del procesador Jack hacen no trabajar con procesadores en el directorio /test. me cambié a apto y funciona bien Entonces, si necesita esta funcionalidad, deshágase de Jack y use apt.

    –Jason Robinson

    7 de julio de 2017 a las 2:54

  • Recuerde ejecutar las pruebas o ejecutar assembleAndroidTest para ver realmente la clase de dependencia DaggerMyComponent resuelto, simplemente rebuild no generará las clases de daga.

    – jamesbluecrow

    1 de diciembre de 2017 a las 12:25

avatar de usuario
k_o_

Para Android Studio 3 y dagger 2.13 se necesitan los procesadores de anotación ya mencionados:

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

Pero tampoco olvide hacer esto para la prueba instrumentada bajo androidTest:

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

Puede tener la impresión de que esto por sí solo no funciona, porque las clases DaggerXYZ no se generan. Después de horas, descubrí que la generación de la fuente de prueba solo se activa cuando se ejecutan las pruebas. Si empiezas un test o androidTest desde Android Studio, se debe activar la generación de fuentes.

Si necesita este gradle desencadenante anterior manualmente:

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

Reemplazar Debug si ejecuta una prueba en un tipo de compilación diferente.

Nota:

Si está utilizando multiDexEnable = true, es posible que obtenga un error:

La ejecución de la prueba falló: la ejecución de la instrumentación falló debido a ‘java.lang.IncompatibleClassChangeError’

Use un corredor diferente en este caso:

android {

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

  • Sí, necesita ejecutar algunas de las pruebas y luego Dagger generará las clases de daga de prueba (componentes) +1

    – Stoycho Andreev

    1 oct 2018 a las 19:39

  • siempre he pensado que rebuild pasa por todo el proyecto, pero obviamente no. Gracias hombre.

    – Viacheslav

    20 de febrero de 2019 a las 12:33

  • androidTestAnnotationProcessor: eso es lo que estaba buscando, ¡gracias!

    – Johan Lund

    29 de enero de 2021 a las 10:30

avatar de usuario
carlosgoncalves

Solo para agregar un poco a la respuesta anterior, ya que ha habido algunos cambios recientes.

Desde el complemento Android Gradle versión 2.2 y superior ya no usará testApt.

Entonces, de ahora en adelante, solo necesita poner esto en build.gradle:

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

Pero más que eso, a lo que vine aquí es a lo siguiente: si necesita gradle para generar las clases DaggerComponent para usted tendrás que hacer un poco de trabajo extra.

Abra nuestro archivo build.gradle y DESPUÉS de la sección de Android escriba esto:

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')
    }
}

Esto creará el directorio build/generated/source/apt/test/ como un destinatario de clases de Java y la última parte activará la tarea “assembleDebugUnitTest” que finalmente creará esos componentes Dagger2 en la carpeta que se acaba de crear.

Tenga en cuenta que este script solo se activa para la variante de “depuración” y aprovecha esa variante de compilación mediante la tarea “assembleDebug”. Si por alguna razón lo necesita en otras variantes, ajústelo un poco.

No entiendo por qué Dagger2 no hace esto automáticamente, pero bueno, no soy un profesional.

  • Funciona para mí, te has perdido el final. }

    – Efi MK

    6 sep 2017 a las 18:54

  • Me gustó este enfoque porque no requiere más bibliotecas de Android para instalar. Debido a que estoy haciendo TDD en una biblioteca separada, comencé con android.libraryVariants.all

    – Juan Méndez

    12/09/2017 a las 21:11

  • Fantástico. Después de buscar durante horas una alternativa a testApt, esto hizo el truco. ¡Gracias!

    – sal y pimienta

    19 de septiembre de 2017 a las 14:05

  • @saltandpepper ¿algún problema que tenga con la última versión de gradle?

    – Shishir Shetty

    27 de abril de 2018 a las 19:03

  • Gracias. Me tomó 2 días arreglarlo. Kotlin + Dagger 2.19 + último gradle

    –Andrii Kovalchuk

    8 de noviembre de 2018 a las 18:20

Agregando a la solución anterior y agregando testKapt y androidTestKapt para dagger, tuve el problema de que mis módulos y componentes tenían importaciones incorrectas como resultado de importaciones faltantes

p.ej

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

en vez de

import dagger.Module
import dagger.Provides

Espero que esto ayude

  • Recomiendo esta respuesta porque te ayuda a ver si hay algún problema con tu gráfico de dependencia u otras cosas fuera de las dependencias.

    – Óscar Josué Álvarez

    28 de febrero de 2019 a las 19:11

  • Me salvaste el día, hermano, estuve atrapado en este problema durante mucho tiempo.

    – Rizwan

    2 de septiembre de 2019 a las 4:44

Hola, incluso después de agregar todas las dependencias y anotaciones de gradle, si aún no funciona, debe ejecutar el script de gradle de la prueba de ensamblaje de Android para esto. Simplemente haga un caso de prueba vacío y ejecútelo. Hará el trabajo por ti. Salud

  • ¡DIOS MÍO! Perdí mucho tiempo con la opción “construir”. pero en realidad los archivos dagger se crean ejecutando incluso una prueba vacía.

    – Marjan Davodineyad

    26 ene a las 14:10

avatar de usuario
Dalvinder Singh

Si está usando kotlin, use “kaptAndroidTest” para generar el componente dagger para las pruebas de Android en su archivo build.gradle.

  • ¡DIOS MÍO! Perdí mucho tiempo con la opción “construir”. pero en realidad los archivos dagger se crean ejecutando incluso una prueba vacía.

    – Marjan Davodineyad

    26 ene a las 14:10

avatar de usuario
elíptica1

corrí ./gradlew build desde la línea de comandos y obtuve información sobre un método Provides faltante del que Android Studio no me habló.

¿Ha sido útil esta solución?