如何将MockModule注入DaggerAppComponent?

时间:2018-07-13 18:24:46

标签: android dagger-2 dagger daggermock

我使用Dagger Android已有一段时间了,现在我想注入MockModule进行测试,但我不知道如何获得它。我在一些帖子上看到他们称呼类似:

DaggerAppComponent.builder()
  .dataModule(myMockModule)
  .create(this).inject(this)

但是我有这个配置:

@Singleton
@Component(modules = [
    AndroidSupportInjectionModule::class,
    ActivitiesBuilderModule::class,
    AppModule::class,
    DataModule::class
])
internal interface AppComponent : AndroidInjector<CbvApplication> {

    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<CbvApplication>()

}

,当我创建应用程序时,DaggerAppComponent.Builder没有为各个模块提供setters。在应用程序代码中,这是很好的原因,我不必担心,但是在测试时,我想通过模拟组件/模块注入模拟对象。

任何人都可以向我指出正确的方向?

1 个答案:

答案 0 :(得分:0)

据我所知,我不确定我们是否可以一起模拟整个模块,但可以模块提供的模拟依赖项。 我已经实现了这一点,我需要模拟 DataModule 进行UI测试,所以我创建了TestDataModule并为依赖项提供了模拟。

import com.nhaarman.mockito_kotlin.mock
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module
class TestDataModule {

    @Provides
    @Singleton
    fun providesDataRepository(): DataRepository {
        return mock()
    }
}

这里是TestApplicationModule

@Module
abstract class TestApplicationModule {

    @Binds
    abstract fun bindContext(application: Application): Context
}

并创建了TestApplicationComponent,它将使用所需的模块

@Singleton
@Component(modules = [
    (AndroidSupportInjectionModule::class),
    (TestApplicationModule::class),
    (UIModule::class),
    (PresentationModule::class),
    (TestDataModule::class)])
interface TestApplicationComponent {

    // Here you can add additional direct mock 
    // classes to access them directly from component reference
    fun dataRepository(): DataRepository 


    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): TestApplicationComponent.Builder

        fun build(): TestApplicationComponent
    }

    fun inject(app: TestAppplication)
}

我必须使用Android JUnit Test Runner和espresso来测试UI,所以我照原样使用了UIModule和Presentation Module(无法按需测试进行模拟)。因此,必须模拟其他不属于该UI单元测试的依赖项,例如 DataRepository

您可以将诸如CacheModule和RemoteModules之类的其他模块添加为模拟对象,因为它们在UI单元测试中不起作用。

最后,像这样在DaggerTestApplicationComponent中创建TestApplication

class TestApplication : Application(), HasActivityInjector {

    @Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity>
    private lateinit var appComponent: TestApplicationComponent

    override fun onCreate() {
        super.onCreate()
        appComponent = DaggerTestApplicationComponent.builder()
                .application(this)
                .build()
        appComponent.inject(this)
    }

    override fun activityInjector(): AndroidInjector<Activity> = activityInjector
}

因此,现在DaggerTestApplicationComponent将生成所需的依赖关系图。

注意:需要对模拟依赖项上调用的所有方法进行存根处理