Plain Dagger: override binding from included module in Android instrumentation test
I’m working with a large legacy Android codebase using plain Dagger, not Hilt.
Production component:
@Component(modules = [BaseModule::class])
interface AppComponent
"BaseModule" internally includes many modules and one of those modules provides a real repository binding.
Test component:
@Component(modules = [BaseModule::class])
interface TestAppComponent : AppComponent
I want to replace one repository dependency with a fake implementation in instrumentation tests.
I tried adding a fake module:
@Module
class FakeRepositoryModule {
@Provides
fun provideRepository(
fake: FakeRepository
): Repository = fake
}
Then:
@Component(
modules = [
BaseModule::class,
FakeRepositoryModule::class
]
)
interface TestAppComponent : AppComponent
But Dagger fails with a duplicate binding error because "BaseModule" already includes the real binding for "Repository".
Constraints:
- I cannot remove "BaseModule" from "TestAppComponent"
- I cannot modify/split "BaseModule"
- I cannot migrate to Hilt
- The graph is very large and shared across many features
Is there any way in plain Dagger to override or replace a binding from an included module in a test component without changing the original module graph?
Or is the only real solution to introduce a test seam, such as splitting the module, using component dependencies, or faking a lower-level dependency instead?