Issue
If we just use plain dagger 2. In the application class, we will have a property which holds the AppComponent. Then we can swap it during espresso tests.
But when I setup my project using dagger-android 2.15. Things becomes more implicit if adopt too much Dagger magic. The code is more clean, but makes testing a little bit hard.
This is the application class:
class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent
.builder()
.create(this)
.build()
}
}
This is the HomeActivity
class HomeActivity : DaggerAppCompatActivity() {
@Inject
lateinit var userPreference: UserPreference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
if (!this.userPreference.memberRegistered) {
goToActivity(EntryActivity::class.java)
}
}
}
Take this code for example. How to mock that injected userPreference.memberRegistered Which could be a HTTP call underneath?
Solution
I wrote a blog post that explains how to do this just yesterday: https://dev.to/autonomousapps/the-daggerandroid-missing-documentation-33kj
I don't intend to repeat the entire post for this answer (it's hundreds of words and lines of code to properly set up a test harness with Dagger), but to attempt to summarize:
- Add a custom application class in the
debugsource set (I assume it would also work in theandroidTestsource set, but I have not tried this). - You also need to reference this application in a
AndroidManifest.xmlin the same source set. - Create a "Test component" in your androidTest class that extends from your production top-level component and build it.
- Use that test component to inject your application, which means you've just replaced your entire Dagger dependency graph with a new one you've defined just for the test suite.
- Profit.
Answered By - AutonomousApps
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.