2016-03-26 9 views
41

Ich bin nach der Anleitung hier: https://github.com/ecgreb/dagger-2-testing-demoDagger nicht erzeugenden Komponenten für/Testklasse

Ich habe die folgende Setup in meiner app/src/main (die Injektion und @Provides Code weggelassen):

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

@Module 
public class FlingyModule 

In app/src/test:

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

@Module 
public class TestFlingyModule 

Bisher ist es zum Beispiel github nahezu identisch. Wenn Dolch den Code für die Komponenten-Builder in src/main generiert, werden sie ordnungsgemäß generiert. Dolch generiert jedoch keinen Code für die Komponenten-Builder in src/test.

Mein Haupt build.gradle:

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

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

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

Also, wenn ich bauen, bekomme ich die DaggerFlingyApplication_FlingyComponent Klasse, aber nicht die DaggerTestFlingyApplication_TestFlingyComponent

Etwas Interessant ist mir aufgefallen, dass wenn ich die Leitung umschalte:

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

Ich sehe die folgende wenn ich ./gradlew compileDebugUnitTestSources laufen:

: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. 

Ich weiß nicht, warum es auf Intermediates baut und ich nehme an, dass ich die build.gradle Datei benötigen apt zu verwenden, anstatt compile, aber ich Ich kann mir nicht vorstellen, wie ich das zur Arbeit bringen soll. Ich weiß, dass es absolut möglich ist.

+0

Diese Dokumentation (http : //google.github.io/dagger/testing.html) Ratschläge, Dolch nicht für Komponententests zu verwenden. –

+0

Wenn Sie viele Abhängigkeiten haben, dann könnte es p Wenn Sie mehr als eine einzelne Einheit testen möchten, Das heißt, Google weiß nicht immer am besten (keuch!) Und das ist eine ziemlich breite Aussage von ihnen. Die Verwendung von Dolch in Einzeltests in bestimmten Fällen funktioniert gut für uns, daher diese Frage. – jyanks

Antwort

83

Sie müssen Folgendes zu Ihrer build.gradle Datei für die Instrumentierung Test hinzuzufügen:

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

oder für JUnit-Test:

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

Dies ist erforderlich, Dagger-Code für Ihre Testkomponenten zu erzeugen.


EDIT:

Wenn Sie jack Werkzeugkette verwenden, dann folgt für Android Test hinzufügen:

für JUnit-Tests:

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

EDIT:

Falls Sie verwenden kotlin-kapt für Kotlin Code Verwendung folgenden:

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

oder für JUnit-Test:

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

prüfen this Link für weitere Informationen.

+0

Auch wenn die Tests in/Test sind, nicht/androidTest? – jyanks

+0

Sie schreiben Instrumententest, der in 'androidTest' sein sollte. Wenn Sie JUnit test schreiben, können Sie 'testApt' verwenden. – Abdullah

+4

Ich bekomme folgendes: '' 'Fehler: (55, 0) Gradle DSL Methode nicht gefunden: 'testApt()'' '' – jyanks

16

Nur um ein wenig zu der obigen Antwort hinzuzufügen, da es kürzlich einige Änderungen gab.

Ab Android Gradle Plugin Version 2.2 und höher verwenden Sie nicht mehr testApt.

Von nun an Sie dies nur in der build.gradle setzen müssen:

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

Aber mehr als das, was ich hier bin, ist die folgende: wenn Sie gradle müssen die erzeugen DaggerComponent Klassen für Sie müssen Sie ein bisschen mehr Arbeit zu tun.

Öffnen Sie unsere build.gradle Datei und nach dem Android-Abschnitt schreiben dies:

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

Dies wird das Verzeichnis build/erzeugt/Quelle/apt/Test/als Java-Klassen Empfänger und der letzte Teil wird erstellen triggert den Task "assembleDebugUnitTest", der diese Dagger2-Komponenten in dem gerade erstellten Ordner erstellt.

Beachten Sie, dass dieses Skript gerade für die "Debug" -Variante ausgelöst wird und diese Build-Variante mit der Task "assembleDebug" nutzt. Wenn Sie es aus anderen Gründen in anderen Varianten benötigen, dann ändern Sie das ein wenig.

Warum Dagger2 dies nicht automatisch macht, ist mir ein Rätsel, aber hey, ich bin kein Profi.

+0

Works für mich, haben Sie die Endung '}' –

+0

Ich mochte diesen Ansatz, weil es nicht mehr Android-Bibliotheken zur Installation benötigt. Da ich TDD in einer separaten Bibliothek mache, habe ich mit android.libraryVariants.all begonnen. –

+0

Fantastic. Nachdem ich stundenlang nach einer Alternative zu "testApt" gesucht hatte, war das der Trick. Vielen Dank! – saltandpepper

7

Für Android Studio 3 und Dolch 2.13 die bereits erwähnten Anmerkung Prozessoren benötigt werden:

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

Aber auch die dies unter androidTest für die instrumentierte Test tun nicht vergessen:

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

Sie könnten habe den Eindruck, dass das alleine nicht funktioniert, weil die DaggerXYZ-Klassen nicht generiert werden.Nach Stunden habe ich herausgefunden, dass die Testquellengenerierung nur ausgelöst wird, wenn die Tests ausgeführt werden. Wenn Sie ein test oder androidTest von Android Studio starten, sollte die Quellengenerierung ausgelöst werden.

Wenn Sie diese früher Trigger gradle müssen manuell:

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

Debug ersetzen, falls Sie Test in einem anderen Build-Typ ausgeführt werden.

Hinweis:

Wenn Sie multiDexEnable verwenden = true Sie möglicherweise eine Fehlermeldung erhalten:

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

Verwenden Sie einen anderen Läufer in diesem Fall:

android { 

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