title: Android Unit Tests with Dagger 2
body: <p>I have an Android app that uses Dagger 2 for dependency injection. I am also using the latest gradle build tools that allow a build variant for unit testing and one for instrumentation tests. I am using <code>java.util.Random</code> in my app, and I want to mock this for testing. The classes I'm testing don't use any Android stuff, so they're just regular java classes.</p>
  
  <p>In my main code I define a <code>Component</code> in a class that extends the <code>Application</code> class, but in the unit tests I'm not using an <code>Application</code>. I tried defining a test <code>Module</code> and <code>Component</code>, but Dagger won't generate the <code>Component</code>. I have also tried using the <code>Component</code> that I defined in my application and swapping the <code>Module</code> when I build it, but the application's <code>Component</code> doesn't have <code>inject</code> methods for my test classes. How can I provide a mock implementation of <code>Random</code> for testing?</p>
  
  <p>Here's some sample code:</p>
  
  <p>Application:</p>
  
  <pre><code>public class PipeGameApplication extends Application {
  
      private PipeGame pipeGame;
  
      @Singleton
      @Component(modules = PipeGameModule.class)
      public interface PipeGame {
          void inject(BoardFragment boardFragment);
          void inject(ConveyorFragment conveyorFragment);
      }
  
      @Override
      public void onCreate() {
          super.onCreate();
          pipeGame = DaggerPipeGameApplication_PipeGame.create();
      }
  
      public PipeGame component() {
          return pipeGame;
      }
  }
  </code></pre>
  
  <p>Module:</p>
  
  <pre><code>@Module
  public class PipeGameModule {
  
      @Provides
      @Singleton
      Random provideRandom() {
          return new Random();
      }
  }
  </code></pre>
  
  <p>Base class for tests:</p>
  
  <pre><code>public class BaseModelTest {
  
      PipeGameTest pipeGameTest;
  
      @Singleton
      @Component(modules = PipeGameTestModule.class)
      public interface PipeGameTest {
          void inject(BoardModelTest boardModelTest);
          void inject(ConveyorModelTest conveyorModelTest);
      }
  
      @Before
      public void setUp() {
          pipeGameTest = DaggerBaseModelTest_PipeGameTest.create(); // Doesn't work
      }
  
      public PipeGameTest component() {
          return pipeGameTest;
      }
  }
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>public class BaseModelTest {
  
      PipeGameApplication.PipeGame pipeGameTest;
  
      // This works if I make the test module extend
      // the prod module, but it can't inject my test classes
      @Before
      public void setUp() {
          pipeGameTest = DaggerPipeGameApplication_PipeGame.builder().pipeGameModule(new PipeGameModuleTest()).build();
      }
  
      public PipeGameApplication.PipeGame component() {
          return pipeGameTest;
      }
  }
  </code></pre>
  
  <p>Test Module:</p>
  
  <pre><code>@Module
  public class PipeGameTestModule {
  
      @Provides
      @Singleton
      Random provideRandom() {
          return mock(Random.class);
      }
  }
  </code></pre>