Replace a production NetworkService with a fake in Hilt instrumented tests

Tests whether you know Hilt test overrides beyond basic DI. A strong answer covers @BindValue for field-level fakes and @TestInstallIn or @UninstallModules for module swaps.
WHAT THIS TESTS: This question probes whether you understand Hilt's dedicated testing infrastructure for Android instrumented tests, specifically how to swap production bindings without mutating production code or resorting to manual dependency injection. At the senior level, the interviewer wants to see that you know the difference between field-level overrides and module-level replacements, and that you can pick the right tool based on binding complexity and test scope.
A GOOD ANSWER COVERS: A good answer covers four things in order. First, mention @BindValue as the simplest mechanism: annotate a FakeNetworkService field in the test class with @BindValue, and Hilt will install that instance into the graph, overriding the production binding. Second, explain when module replacement is better: if the fake has its own dependencies or you need to replace multiple bindings together, use @UninstallModules on the test class to strip out the production module, then provide a test module annotated with @InstallIn. Third, mention @TestInstallIn as an alternative that lets you annotate a test module class itself to replace a production module without using @UninstallModules in every test. Fourth, note that these APIs only work inside a @HiltAndroidTest class that uses HiltAndroidRule.
COMMON WRONG ANSWERS: Red flags include proposing to add a setNetworkService method in the production class for testing, using reflection to swap fields after injection, or building a custom Dagger component in the test. Another wrong pattern is claiming you must duplicate the entire production module manually; the correct pattern is uninstalling the specific module you are overriding. Some candidates also confuse @BindValue with @Inject in tests; @BindValue is for providing into the graph, not for requesting from it.
LIKELY FOLLOW-UPS: The interviewer may ask how you would handle a multibinding scenario, which requires @BindValueIntoSet or @BindValueIntoMap instead of plain @BindValue. They might also ask how to share the same fake instance across multiple test classes, which points toward defining a reusable test module rather than inline @BindValue fields. A third follow-up is how Hilt handles the same binding defined in both a production and test module, which tests your understanding of @UninstallModules precedence.
ONE CONCRETE EXAMPLE: Suppose NetworkService is bound in a ProductionNetworkModule. In your instrumented test class annotated with @HiltAndroidTest, you can declare a field annotated with @BindValue and assign it a new FakeNetworkService instance. This immediately overrides the real implementation for every injected consumer in that test. If FakeNetworkService itself requires a test-only OkHttpClient configuration, you would instead annotate the test class with @UninstallModules specifying ProductionNetworkModule, then define a TestNetworkModule annotated with @InstallIn for the SingletonComponent that binds FakeNetworkService. For a suite of twenty tests that all need the same fake, place @TestInstallIn on the TestNetworkModule to replace ProductionNetworkModule globally for that source set.
Read the original → developer.android.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.