JFYI : overriding @Module classes with Dagger 2 [in tests]
You can override @Module
class, for example for tests.
But annotations on overridden @Provides
methods eg @Singleton
, @Named
, etc won't override original ones because Dagger 2 generates code for initial @Module
+ @Component
classes (for @Module
mentioned in @Component(modules = …)
.
Yes, you can pass overridden implementations when you build an instance of @Component
but it won't affect generated code.
Example, main code
@Module
public class SomeModule {
@Provides @NonNull @Named("very_special_thing") @Singleton
public SomeThing provideSomeThing(@NonNull SomeArgs someArgs) {
return new SomeThing(someArgs);
}
}
@Component(modules = SomeModule.class)
public interface SomeComponent {
void inject(@NonNull TargetClass target);
}
In tests
// No need for @Module annotation
public class SomeModuleForTest extends SomeModule {
// No need for DI annotations here.
// Even if you put annotations like @Named, @Singleton, etc
// they won't affect generated code so you can't override this behavior of original @Module class.
@Override
public SomeThing provideSomeThing(@NonNull SomeArgs someArgs) {
return mock(SomeThing.class);
}
}
Then you can pass overridden module:
SomeComponent someComponent = new DaggerSomeComponent.Builder()
.someModule(new SomeModuleForTest())
.build();
That's it. Mostly it does not matter since you want same behavior in TestModule
as the original @Module
, but JFYI ¯_(ツ)_/¯.
Moreover, looks like it's not possible to support such feature easily because actually, scoping annotations affect code generated for a @Component
, not the @Module
.