I am following the guide here: https://github.com/ecgreb/dagger-2-testing-demo
I have the following setup in my app/src/main (the injection and @Provides code omitted):
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
So far, it is nearly identical to the example github. When dagger goes to generate the code for the Component builders in src/main, they generate properly. Dagger does not, however, generate code for the Component builders in src/test.
My main build.gradle:
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0-alpha3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.5.1'
}
My 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'
}
So when I build, I get the DaggerFlingyApplication_FlingyComponent
class, but not the DaggerTestFlingyApplication_TestFlingyComponent
Something interesting I noticed is that if I switch the line:
apt 'com.google.dagger:dagger-compiler:2.0.1'
# TO
compile 'com.google.dagger:dagger-compiler:2.0.1'
I see the following when I run ./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.
I don't know why it builds to intermediates and I assume that I need the build.gradle file to use apt
instead of compile
, but I can't seem to figure out how to get this to work. I know that it's absolutely possible.
Adding to the above solution and adding the testKapt and androidTestKapt for dagger, I had the problem that my modules and components had the wrong imports as a result of missing imports
e.g
instead of
Hope this helps
If you added kaptAndroidTest for dagger dependencies and still not getting test components when rebuild your project, try running assembleAndroidTest.
You need to add following to your
build.gradle
file for instrumentation test:or for JUnit test:
This is required to generate Dagger code for your test components.
EDIT:
If you are using
jack
tool chain then add following for android test:for JUnit tests:
EDIT:
In case you are using
kotlin-kapt
for Kotlin code use following:or for JUnit test:
Check this link for more info.
Just to add a bit to the above answer, since there have been some recent changes.
From Android Gradle plugin version 2.2 and above you will no longer use testApt.
So from now on you need to put only this in the build.gradle:
But more than that, what I came here for, is the following: if you need gradle to generate the DaggerComponent classes for you you will have to do a bit extra work.
Open our build.gradle file and AFTER the android section write this:
This will create the directory build/generated/source/apt/test/ as a Java classes recipient and the last part will trigger the "assembleDebugUnitTest" task that will finally create those Dagger2 components in the folder that was just created.
Note that this script is just being triggered for the "debug" variant and takes advantage of that build variant using the "assembleDebug" task. If for some reason you need it in other variants just tweak that a bit.
Why Dagger2 does not do this automatically is beyond me, but hey, I am no pro.
For Android Studio 3 and dagger 2.13 the already mentioned annotation processors are needed:
But also do not forgot the do this for the instrumented test under
androidTest
:You might get the impression that this alone does not work, because the DaggerXYZ classes are not generated. After hours I found out that the test source generation is only triggered when the tests are executed. If you start a
test
orandroidTest
from Android Studio the source generation should be trigger.If you need this earlier trigger gradle manually:
Replace
Debug
if you run test in a different build type.Note:
If you are using multiDexEnable = true you might get an error:
Use a different runner in this case:
If you are using kotlin use "kaptAndroidTest" to generate dagger component for android tests in your build.gradle file.