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

jon*_*ney 5 android automated-tests unit-testing android-espresso dagger-2

您可以在我的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
    }

}
Run Code Online (Sandbox Code Playgroud)

我可以直接将测试模块添加到testAppComponent,但它不能为我提供动态添加不同testModule的灵活性.

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的MyApplication类

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)
    }

}
Run Code Online (Sandbox Code Playgroud)

在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)
    }
Run Code Online (Sandbox Code Playgroud)

我正在遵循这个指南直到我偶然发现我的DaggerTestAppComponent没有公开模块让我动态添加自己,因为我的AppComponent类扩展了AndroidInjector,它会自动为你添加模块

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

以上动态添加其模块如下:

testAppComponent = DaggerTestAppComponent.builder()
                .appModule(AppModule(app))
                .apiModule(TestApiModule())
                .prefModule(TestPrefModule())
                .build()
Run Code Online (Sandbox Code Playgroud)

除非我重做我的AppComponent以便它不会扩展AndroidInjector,否则我无法在我的情况下这样做.如果我这样做,那么在我真正的impl代码中,我必须手动设置模块.

还有其他方法吗?

Sav*_*nar 1

您应该向组件构建器添加一个函数并使用“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();
  }
}
Run Code Online (Sandbox Code Playgroud)

在此组件中,我使用“BindsInstance”添加了 applicationModule 函数,并且可以通过 ApplicationTestModule。

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

TestApplicationComponent appComponent = DaggerTestAppComponent.builder().application(this).
applicationModule(appTestModule).build();
appComponent.inject(this);
Run Code Online (Sandbox Code Playgroud)