3

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 ?

j2emanue
  • 60,549
  • 65
  • 286
  • 456

1 Answers1

1

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)
}
j2emanue
  • 60,549
  • 65
  • 286
  • 456