Injecting test module with dagger2

荒凉一梦 提交于 2020-01-03 13:31:09

问题


I use Dagger2 in my android app. Basically I inject a HttpClient (interface) in MainActivity.

@Module
public class MainActivityModule{

   @Provides public HttpClient providesHttpComponent(){
        return new RealHttpClient();
    }
}

@Component( modules = MainActivityModule.class )
public interface MainActivityComponent {
   public MainActivity injectActivity(MainActivity);
}



public class MainActivity extends Activity {

   public void onCreate(Bundle saved){
      super.onCreate();

      injectDependencies();
   }


   protected void injectDependencies(){

      Dagger_MainActivityComponent
        .builder()
        .mainActivityComponent( new MainActivityModule())
        .build()
        .injectActivity(this);
   }

}

So far so good, that works like expected. Now I want to write some unit tests (not android instrumentation tests) for MainActivity where I want to use TestMainActivityModule instead of MainActivityModule.

@Module (overrides = true )
public class TestMainActivtiyModule extends MainActivityModule {

   @Provides public HttpClient(){
      return new MockHttpClient();
   }

}

My question is: How do I force MainActivity to use TestMainActivitiyModule instead of MainActivityModule? Is there a good solution for that?

My current approach is to use inheritance and to override getModule(), something like this

public class TestMainActivity extend MainActivity {

   @Override
   protected void injectDependencies(){

      Dagger_MainActivityComponent
        .builder()
        .mainActivityComponent( new TestMainActivtiyModule())
        .build()
        .injectActivity(this);
   }
}

and to run unit test against TestMainActivity instead of MainActivity.

I guess it works, but one of the problems I'm facing with this approach is that I can't start TestMainActivity with an Intent because I can't specify it in AndroidManifest.xml

Does anyone know a better approach for unit testing with dagger2 on android?


回答1:


The approach I've started using has involved maintaining two modules (one for the app, one for testing) in parallel build variants (ex: app and integration). Still not sure how well that solution scales so YMMV. I'd be very happy to see a better solution!

This is also a great read: http://engineering.circle.com/instrumentation-testing-with-dagger-mockito-and-espresso/




回答2:


I would really suggest you to check this boilerplate since it is fully based on DI using Dagger2. It also shows how you can replace your dependencies in the test environment in a very neat way.

The dependencies currently handled by the boiler plate are the following:

  • Database dependency: encapsulates all the database operations.
  • Shared preferences dependency: deals with shared preferences.
  • Local files dependency: which deals with saving on files.
  • Analytics dependency: covers all the operation of reporting events to your analytics backend (GA, Segment, FB, Flurry ..)
  • Logging dependency: encapsulates all the operations related to logging to your console
  • Api dependency: encapsulates all the API related operations

The power of dependency injection comes really handy especially for testing since you can easily switch your dependencies in the test environment to dummy dependencies.



来源:https://stackoverflow.com/questions/29259688/injecting-test-module-with-dagger2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!