forked from square/dagger
-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hilt: allow custom injection support for tests.
One of the key decisions with Hilt is bytecode rewriting. It helps simplify the developer experience, but makes things more complicated for testing. As a result Hilt provides additional testing framework that helps mitigate these concerns and allows for great flexibility when it comes to mocking and replacing dependencies for testing. Still, hilt has non-trivial compilation costs. And as the codebase growth, we've observed that the cost for test complication growth even more so than for production code. As a result there is an exploration to avoid using hilt for simpler cases where the value of DI graph in tests is very small, but the additional costs to compile are great. This diff introduces a few small touches to Hilt codegen to allow for a runtime test DI (like a simpler version of Guice) to overtake the injection. Specifically, this diff introduces `TestInjectInterceptor` class with a single empty static method `injectForTesting()`. The codegen for Activities, Fragments, Views, Services, and Broadcasts is adjusted to have the next code: ``` protected void inject() { if (!injected) { injected = true; if (TestInjectInterceptor.injectForTesting(this)) { return; } // rest of Hilt injection code. } ``` For production or tests running under Hilt the additional code does nothing. And for production this code should be eliminated by R8. But for cases where testing framework is able to intercept a call to `TestInjectInterceptor.injectForTesting()` (like Robolectric shadow), the injection can be overtake in a consistent manner for all types of supported android entry points.
- Loading branch information
Showing
8 changed files
with
41 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
java/dagger/hilt/android/internal/managers/TestInjectInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package dagger.hilt.android.internal.managers; | ||
|
||
/** | ||
* This class does nothing in production or in tests when running under Hilt testing framework. However, the calls | ||
* to TestInjectInterceptor.injectForTesting() are done in a few strategic places just before Hilt does the injection | ||
* into Android Components. | ||
* | ||
* As a result this class enables non-Hilt based frameworks to take over the injection process. | ||
*/ | ||
public class TestInjectInterceptor { | ||
/** | ||
* This method always returns false by default. However, if this method is intercepted during testing | ||
* by frameworks like Robolectric, the intercepting code can take over the injection process and | ||
* instruct Hilt to skip doing anything extra for this instance. | ||
* | ||
* Return false if no custom injection was done and Hilt should continue as normal. Return true | ||
* if the testing framework has takes over the injection process and Hilt should skip any extra | ||
* work. | ||
*/ | ||
public static boolean injectForTesting(Object injectTo) { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# Keep for the reflective cast done in EntryPoints. | ||
# See b/183070411#comment4 for more info. | ||
-keep,allowobfuscation,allowshrinking @dagger.hilt.android.EarlyEntryPoint class * | ||
-keep,allowobfuscation,allowshrinking @dagger.hilt.android.EarlyEntryPoint class * | ||
-assumenosideeffects class dagger.hilt.android.internal.managers.TestInjectInterceptor { *; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters