How do you override a module/dependency in a unit test with Dagger 2.0?

后端 未结 8 2425
一个人的身影
一个人的身影 2020-11-30 19:13

I have a simple Android activity with a single dependency. I inject the dependency into the activity\'s onCreate like this:

Dagger_HelloComponen         


        
8条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-11-30 19:46

    Can you guys check out my solution, I have included subcomponent example: https://github.com/nongdenchet/android-mvvm-with-tests. Thank you @vaughandroid, I have borrowed your overriding methods. Here is the main point:

    1. I create a class to create subcomponent. My custom application will also hold an instance of this class:

      // The builder class
      public class ComponentBuilder {
       private AppComponent appComponent;
      
       public ComponentBuilder(AppComponent appComponent) {
        this.appComponent = appComponent;
       }
      
       public PlacesComponent placesComponent() {
        return appComponent.plus(new PlacesModule());
       }
      
       public PurchaseComponent purchaseComponent() {
        return appComponent.plus(new PurchaseModule());
       }
      }
      
      // My custom application class
      public class MyApplication extends Application {
      
       protected AppComponent mAppComponent;
       protected ComponentBuilder mComponentBuilder;
      
       @Override
       public void onCreate() {
        super.onCreate();
      
        // Create app component
        mAppComponent = DaggerAppComponent.builder()
                .appModule(new AppModule())
                .build();
      
        // Create component builder
        mComponentBuilder = new ComponentBuilder(mAppComponent);
       }
      
       public AppComponent component() {
        return mAppComponent;
       }
      
       public ComponentBuilder builder() {
        return mComponentBuilder;
       } 
      }
      
      // Sample using builder class:
      public class PurchaseActivity extends BaseActivity {
       ...    
       @Override
       protected void onCreate(Bundle savedInstanceState) {
        ...
        // Setup dependency
        ((MyApplication) getApplication())
                .builder()
                .purchaseComponent()
                .inject(this);
        ...
       }
      }
      
    2. I have a custom TestApplication that extends the MyApplication class above. This class contains two methods to replace the root component and the builder:

      public class TestApplication extends MyApplication {
       public void setComponent(AppComponent appComponent) {
        this.mAppComponent = appComponent;
       }
      
       public void setComponentBuilder(ComponentBuilder componentBuilder) {
        this.mComponentBuilder = componentBuilder;
       }
      }    
      
    3. Finally I will try to mock or stub the dependency of module and builder to provide fake dependency to the activity:

      @MediumTest
      @RunWith(AndroidJUnit4.class)
      public class PurchaseActivityTest {
      
       @Rule
       public ActivityTestRule activityTestRule =
           new ActivityTestRule<>(PurchaseActivity.class, true, false);
      
       @Before
       public void setUp() throws Exception {
       PurchaseModule stubModule = new PurchaseModule() {
           @Provides
           @ViewScope
           public IPurchaseViewModel providePurchaseViewModel(IPurchaseApi purchaseApi) {
               return new StubPurchaseViewModel();
           }
       };
      
       // Setup test component
       AppComponent component = ApplicationUtils.application().component();
       ApplicationUtils.application().setComponentBuilder(new ComponentBuilder(component) {
           @Override
           public PurchaseComponent purchaseComponent() {
               return component.plus(stubModule);
           }
       });
      
       // Run the activity
       activityTestRule.launchActivity(new Intent());
      }
      

提交回复
热议问题