代码之家  ›  专栏  ›  技术社区  ›  Jono

在appComponent dagger 2中动态添加测试模块?

  •  5
  • Jono  · 技术社区  · 6 年前

    嗨,可以在我的AppComponent中添加测试模块吗?

    下面是我的appComponent的真实表示

    @Singleton
    @Component(modules = arrayOf(MainModule::class,
            AnalyticsModule::class,
            MainAndroidBinding::class,
            AccountAndroidBinding::class,
            AndroidSupportInjectionModule::class,
            HomeAndroidBinding::class,
            NetworkModule::class))
    interface ApplicationComponent : AndroidInjector<DaggerApplication> {
        fun inject(myApplication: MyApplication)
        override fun inject(instance: DaggerApplication)
    
        @Component.Builder
        interface Builder {
            @BindsInstance
            fun application(applicaton: Application): Builder
            fun build(): ApplicationComponent
        }
    
    }
    

    @Singleton
    @Component(modules = [
        (MainModuleTest::class),
        (TestMainAndroidBindingTest::class),
        (AccountAndroidBindingTest::class),
        (AnalyticsModuleTest::class),
        (AndroidSupportInjectionModule::class),
        (NetworkModuleTest::class)])
    interface TestAppComponent : ApplicationComponent {
    
        fun inject(launchActivityTest: LaunchActivityTest)
    
        @Component.Builder
        interface Builder {
            @BindsInstance
            fun application(applicaton: Application): Builder
    
            fun build(): TestAppComponent
        }
    }
    

    这是我的应用程序类

    class MyApplication : DaggerApplication() {
    
        companion object {
    
            private lateinit var application: MyApplication
    
            fun get(): MyApplication {
                return application
            }
        }
    
    
        @Inject
        lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
    
        lateinit var applicationComponent: ApplicationComponent
    
        override fun onCreate() {
            super.onCreate()
            application = this
        }
    
        override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
            applicationComponent = DaggerApplicationComponent.builder()
                    .application(this)
                    .build()
            applicationComponent.inject(this)
            return applicationComponent
        }
    
        override fun attachBaseContext(base: Context?) {
            super.attachBaseContext(base)
            MultiDex.install(this)
        }
    
    }
    

    在LaunchActivityTest上,这是我如何设置它来使用这个testApp组件的

      @Before
        fun setUp() {
            val app = InstrumentationRegistry.getTargetContext().applicationContext as MyApplication
            val testAppComponent = DaggerTestAppComponent.builder().application(app).build()
            app.applicationComponent = testAppComponent
            testAppComponent.inject(this)
        }
    

    我一直在遵循这个指南,直到我无意中发现我的DaggerTestAppComponent没有公开模块供我动态添加自己,因为我的AppComponent类扩展了androidobjector,它会自动为您添加模块

    https://proandroiddev.com/writing-espresso-instrumentation-tests-with-dagger2-kotlin-d30f12c4769b

    上面的模块是这样动态添加的:

    testAppComponent = DaggerTestAppComponent.builder()
                    .appModule(AppModule(app))
                    .apiModule(TestApiModule())
                    .prefModule(TestPrefModule())
                    .build()
    

    在我的情况下,我不能这样做,除非我重做我的AppComponent,这样它就不会扩展androidinojector。如果我这样做,那么在我真正的impl代码中,我必须手动设置模块。

    1 回复  |  直到 6 年前
        1
  •  1
  •   SavasCinar    6 年前

    您应该在组件生成器中添加一个函数并使用“BindsInstance”。

    示例组件

    @Singleton
    @Component(modules = {
        AndroidSupportInjectionModule.class,
        ApplicationTestModule.class,
        ActivityBuilder.class})
    public interface TestExampleComponent extends AndroidInjector<DaggerApplication> {
    
    void inject(TestApplication app);
    
    @Override
    void inject(DaggerApplication instance);
    
    @Component.Builder
    interface Builder {
        @BindsInstance
        TestExampleComponent.Builder application(DaggerApplication application);
        Builder applicationModule(ApplicationTestModule appTestModule);
        TestExampleComponent build();
      }
    }
    

    在这个组件中,我使用“BindsInstance”添加了applicationModule函数,并且可以传递ApplicationTestModule。

    然后可以添加不同的测试模块。

    TestApplicationComponent appComponent = DaggerTestAppComponent.builder().application(this).
    applicationModule(appTestModule).build();
    appComponent.inject(this);