title: How to test with Dagger2 Dependency Injection & Robolectric in Android?
body: <p>I recently implemented Dagger2 into an Android application for easy dependency injection but after doing so some of my tests have stopped working.</p>
  
  <p>Now I am trying to understand how to adjust my tests to work with Dagger2? I am using Robolectric for running my tests.</p>
  
  <p>Here is how I use Dagger2, I have only recently learned it so this may be bad practice and not helping the tests so please do point out any improvements I can make.</p>
  
  <p>I have an AppModule which is as follows:</p>
  
  <pre><code>@Module
  public class MyAppModule {
  
      //Application reference
      Application mApplication;
  
      //Set the application value
      public MyAppModule(Application application) {
          mApplication = application;
      }
  
      //Provide a singleton for injection
      @Provides
      @Singleton
      Application providesApplication() {
          return mApplication;
      }
  }
  </code></pre>
  
  <p>And what I call a NetworkModule that provides the objects for injection that is as follows:</p>
  
  <pre><code>@Module
  public class NetworkModule {
  
  private Context mContext;
  
  //Constructor that takes in the required context and shared preferences objects
  public NetworkModule(Context context){
      mContext = context;
  }
  
  @Provides
  @Singleton
  SharedPreferences provideSharedPreferences(){
      //...
  }
  
  @Provides @Singleton
  OkHttpClient provideOKHttpClient(){
      //...
  }
  
  @Provides @Singleton
  Picasso providePicasso(){
      //...
  }
  
  @Provides @Singleton
  Gson provideGson(){
      //...
  }
  }
  </code></pre>
  
  <p>And then the Component is like this:</p>
  
  <pre><code>Singleton
  @Component(modules={MyAppModule.class, NetworkModule.class})
  public interface NetworkComponent {
  
      //Activities that the providers can be injected into
      void inject(MainActivity activity);
      //...
  }
  </code></pre>
  
  <p>For my tests I am using Robolectric, and I have a Test variant of my Application class as follows:</p>
  
  <pre><code>public class TestMyApplication extends TestApplication {
  
      private static TestMyApplication sInstance;
      private NetworkComponent mNetworkComponent;
  
      @Override
      public void onCreate() {
          super.onCreate();
          sInstance = this;
          mNetworkComponent = DaggerTestMyApplication_TestNetworkComponent.builder()
                  .testMyAppModule(new TestMyAppModule(this))
                  .testNetworkModule(new TestNetworkModule(this)).build();
      }
  
      public static MyApplication getInstance() {
          return sInstance;
      }
  
      @Override public NetworkComponent getNetComponent() {
          return mNetworkComponent;
      }
  }
  </code></pre>
  
  <p>As you can see I am trying to make sure the mocked versions of my Dagger2 Modules are used, these are mocked as well with the mocked MyAppModule returning the TestMyApplication and the mocked NetworkModule returning mocked objects, I also have a mocked NetworkComponent which extends the real NetworkComponent.</p>
  
  <p>In the setup of a test I create the Activity using Robolectric like this:</p>
  
  <pre><code>//Build activity using Robolectric
  ActivityController&lt;MainActivity&gt; controller = Robolectric.buildActivity(MainActivity.class);
  activity = controller.get();
  
  controller.create(); //Create out Activity
  </code></pre>
  
  <p>This creates the Activity and starts the onCreate, and this is where the issue occurs, in the onCreate I have the following piece of code to inject the Activity into the component so it can use Dagger2 like this:</p>
  
  <pre><code>@Inject Picasso picasso; //Injected at top of Activity
  
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  ButterKnife.bind(this);
  MyApplication.getInstance().getNetComponent().inject(this); 
  
  picasso.load(url).fetch();
  </code></pre>
  
  <p>The problem here is that when running the test I get a NullPointerException on the picasso variable, so I guess my Dagger2 setup has a missing link somewhere for the tests?</p>
  
  <p>EDIT: Adding TestNetworkModule</p>
  
  <pre><code>@Module
  public class TestNetworkModule {
  
      public TestNetworkModule(Context context){
  
      }
  
      @Provides
      @Singleton
      SharedPreferences provideSharedPreferences(){
          return Mockito.mock(SharedPreferences.class);
      }
  
  
      @Provides @Singleton
      Gson provideGson(){
          return Mockito.mock(Gson.class);
      }
  
      @Provides @Singleton
      OkHttpClient provideOKHttpClient(){
          return Mockito.mock(OkHttpClient.class);
      }
  
      @Provides @Singleton
      Picasso providePicasso(){
          return  Mockito.mock(Picasso.class);
      }
  
  }
  </code></pre>