title: Getting Dagger to inject mock objects when doing Espresso functional testing for Android
body: <p>I've recently gone whole-hog with Dagger because the concept of DI makes complete sense. One of the nicer "by-products" of DI (as Jake Wharton put in one of his presentations) is easier testability.</p>
  
  <p>So now I'm basically using Espresso to do some functional testing, and I want to be able to inject dummy/mock data to the application and have the activity show them up. I'm guessing since, this is one of the biggest advantages of DI, this should be a relatively simple ask. For some reason though, I can't seem to wrap my head around it. Any help would be much appreciated. Here's what I have so far (I've written up an example that reflects my current setup):</p>
  
  <pre><code>public class MyActivity
      extends MyBaseActivity {
  
      @Inject Navigator _navigator;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          MyApplication.get(this).inject(this);
  
          // ...
  
          setupViews();
      }
  
      private void setupViews() {
          myTextView.setText(getMyLabel());
      }
  
      public String getMyLabel() {
          return _navigator.getSpecialText(); // "Special Text"
      }
  }
  </code></pre>
  
  <p>These are my dagger modules:</p>
  
  <pre><code>// Navigation Module
  
  @Module(library = true)
  public class NavigationModule {
  
      private Navigator _nav;
  
      @Provides
      @Singleton
      Navigator provideANavigator() {
          if (_nav == null) {
              _nav = new Navigator();
          }
          return _nav;
      }
  }
  
  // App level module
  
  @Module(
      includes = { SessionModule.class, NavigationModule.class },
      injects = { MyApplication.class,
                  MyActivity.class,
                  // ...
  })
  public class App {
      private final Context _appContext;
      AppModule(Context appContext) {
          _appContext = appContext;
      }
      // ...
  }
  </code></pre>
  
  <p>In my Espresso Test, I'm trying to insert a mock module like so:</p>
  
  <pre><code>public class MyActivityTest
      extends ActivityInstrumentationTestCase2&lt;MyActivity&gt; {
  
      public MyActivityTest() {
          super(MyActivity.class);
      }
  
      @Override
      public void setUp() throws Exception {
          super.setUp();
          ObjectGraph og = ((MyApplication) getActivity().getApplication()).getObjectGraph().plus(new TestNavigationModule());
          og.inject(getActivity());
      }
  
      public void test_SeeSpecialText() {
          onView(withId(R.id.my_text_view)).check(matches(withText(
              "Special Dummy Text")));
      }
  
      @Module(includes = NavigationModule.class,
              injects = { MyActivityTest.class, MyActivity.class },
              overrides = true,
              library = true)
      static class TestNavigationModule {
  
          @Provides
          @Singleton
          Navigator provideANavigator() {
              return new DummyNavigator(); // that returns "Special Dummy Text"
          }
      }
  }
  </code></pre>
  
  <p>This is not working at all. My Espresso tests run, but the TestNavigationModule is completely ignored... arr... :(</p>
  
  <p>What am I doing wrong? Is there a better approach to mocking modules out with Espresso? I've searched and seen examples of Robolectric, Mockito etc. being used. But I just want pure Espresso tests and need to swap out a module with my mock one. How should i be doing this?</p>
  
  <p>EDIT:</p>
  
  <p>So I went with @user3399328 approach of having a static test module list definition, checking for null and then adding it in my Application class. I'm still not getting my Test injected version of the class though. I have a feeling though, its probably something wrong with dagger test module definition, and not my espresso lifecycle. The reason I'm making the assumption is that I add debug statements and find that the static test module is non-empty at time of injection in the application class. Could you point me to a direction of what I could possibly be doing wrong. Here are code snippets of my definitions:</p>
  
  <p>MyApplication:</p>
  
  <pre><code>@Override
  public void onCreate() {
      // ...
      mObjectGraph = ObjectGraph.create(Modules.list(this));
      // ...   
  }
  </code></pre>
  
  <p>Modules:</p>
  
  <pre><code>public class Modules {
  
      public static List&lt;Object&gt; _testModules = null;
  
      public static Object[] list(MyApplication app) {
          //        return new Object[]{ new AppModule(app) };
          List&lt;Object&gt; modules = new ArrayList&lt;Object&gt;();
          modules.add(new AppModule(app));
  
          if (_testModules == null) {
              Log.d("No test modules");
          } else {
              Log.d("Test modules found");
          }
  
          if (_testModules != null) {
              modules.addAll(_testModules);
          }
  
          return modules.toArray();
      }
  }   
  </code></pre>
  
  <p>Modified test module within my test class:</p>
  
  <pre><code>@Module(overrides = true, library = true)
  public static class TestNavigationModule {
  
      @Provides
      @Singleton
      Navigator provideANavigator()() {
          Navigator navigator = new Navigator();
          navigator.setSpecialText("Dummy Text");
          return navigator;
      }
  }
  </code></pre>