Search code examples
androidmockitodagger-2

Mocking dependency not listed in module


I am using very simple and likely very common scenario. Here is my sample dependency:

public class MyDependency {
   @Inject
   public MyDependency(...) {
      ...
   }
}

I am not listing the above in any module (that is, there is no @Provides for MyDependency).

My sample use case goes like this:

public class ThePresenter {
   @Inject
   MyDependency myDependency;

   public ThePresenter() {
      App.getInstance().getAppComponent().inject(this);
   }
}

Now I'd like to mock my dependency in unit tests. I don't want to use modules overrides (that would mean I have to add @Provides for all my dependencies marked with @Inject constructors), test components etc. Is there any alternative but standard and simple approach for the problem?


Solution

  • You need to use constructor injection, rather than your injection site inside the Presenter class constructor. Expose your Presenter to dagger2 by adding the @Inject annotation on the constructor (like you have done with the dependency):

    public class ThePresenter {
    
       private final MyDependency myDependency;
    
       @Inject public ThePresenter(MyDependency myDependency) {
          this.myDependency = myDependency;
       }
    }
    

    This then allows inversion of control and supplying the dependency/mock.

    Usage :

    public class ThePresenterTest {
    
       @Mock private MyDependency myDependency;
    
       private ThePresenter presenter;
    
       @Before public void setup() {
          MocktioAnnotations.initMocks(this);
          presenter = new ThePresenter(myDependency);
    
          Mockito.when(myDependency.someMethod()).thenReturn(someValue);
          ....
       }
    }