I am doing a junit testing on a use case i have (MVP architecture if that matters) with dagger2. The problem is i would like to use Dagger2 injection inside of my junit test case sometimes. So i looked into DaggerMock library for this. I have a certain dependency i would like built for me but it keeps returning null. Let me show you how i set up dagger first.
its a single component (tried subcomponents but daggerMock was not happy with it): AppComponent.java:
@Singleton
@Component(modules = {AppModule.class, NetworkModule.class, RepositoryModule.class, UseCaseModule.class, ActivityModule.class, PresenterModule.class})
public interface AppComponent {
void inject(NetworkSessionManager target);
void inject(SplashActivity target);
void inject(AuthenticationActivity target);
void inject(WelcomeActivity target);
void inject(LoginFragment target);
}
The rest of the classes are annotated with @inject. if you annotate with @Inject the class constructor all it means is you dont have to delcare it in the AppComponent interface above.
So here is my test case with DaggerMock:
@Rule
public final DaggerMockRule<AppComponent> rule = new DaggerMockRule<>(AppComponent.class, new AppModule(null),new RepositoryModule(),new NetworkModule(),new UseCaseModule());
StandardLoginInfo fakeLoginInfo;
TestObserver<Login> subscriber;
DoStandardLoginUsecase target_standardLoginUsecase;//this is what im trying to test so its real
@InjectFromComponent
UserDataRepository userDataRepository; //id like this to be a real instance also but it keeps showing as null
@Before
public void setUp() throws Exception {
target_standardLoginUsecase = new DoStandardLoginUsecase(userDataRepository); // this gets passed a null, why ?
subscriber = TestObserver.create();
}
//....
}
if we look at the rule i defined i included all my modules from the appcomponent so i was thinking that i have all dependencies available to me. I passed in null to the AppModule as its expected a context, i dont think its a big deal.
I though the @InjectFromComponent
annotation would give me what i wanted. i even tried @InjectFromComponent(DoStandardLoginUsecase.class)
but that does not work. I want it to go into the AppComponent android
build me a UserDataRepository object. Since i am using all the modules in DaggreMockRule i thought it would not have a hard time to do this ?
How can i get dagger2 to build me a real object ?
The trick here is that whatever you want to inject has to be directly exposed in the component. So for example have your component like this:
@Singleton
@Component(modules = {AppModule.class, TestNetworkModule.class, RepositoryModule.class, ActivityModule.class})
public interface TestAppComponent {
void inject(LoginFragment target);
void inject(SignUpFragment target);
MockWebServer server();
UserDataRepository userDataRepo(); //these two can be injected because they are directly exposed (still put them in your module as usual. this just directly exposes them so daggermock can use them)
}