I have large android application with lots of library modules and dagger components, and I need to write Android UI tests for them. I don't want to create every single dagger component for each module. Instead I want to use dagger components and modules from production code. Is it possible?
If we look at Dagger Hilt's documentation, by default they use production components. Does that mean that it is possible to do the same with Dagger2?
If you need to inject a fake or mock instance of a dependency, you need to tell Hilt not to use the binding that it used in production code and to use a different one instead. To replace a binding, you need to replace the module that contains the binding with a test module that contains the bindings that you want to use in the test.
Dagger components work through code generation, so the graph needs to be understood at compile time. Hilt is a system for automating the generation of modules and components. As such, Hilt's test overrides aren't exactly "using the production component", at least as far as the implementation is concerned: Hilt understands how to generate two slightly different component implementations, one for test and one for production, from the same Gradle file and Component interface. Hilt's tendency to create new components is even true when you use @UninstallModules
in a unit test. From the doc you linked:
Note: As Hilt creates new components for tests that use
@UninstallModules
, it can significantly impact unit test build times. Use it when necessary and prefer using@TestInstallIn
when the bindings need to be replaced in all test classes.
Without Hilt, you can absolutely still use modules that you also use in production, but you'll need to be very careful and diligent in your use of Module.includes
so you can effectively recreate your Dagger component module graphs by hand to match your testing needs. Without Hilt, you'll need to make those configuration changes in separate component interface definitions, and depending on the depth of your component graph you might need to further redefine subcomponents that your components use.
The difficulty in managing this in raw Dagger 2 is one of the primary listed goals for Hilt (emphasis mine):
With respect to Dagger, the goals of Hilt are as follows:
- To simplify Dagger-related infrastructure for Android apps.
- To create a standard set of components and scopes to ease setup, readability, and code sharing between apps.
- To provide an easy way to provision different bindings to various build types, such as testing, debug, or release.