使用Dagger2,Espresso和Mockito对MVVM架构进行Android UI测试

时间:2019-02-27 09:45:54

标签: android mockito dagger-2 android-espresso dagger

我正试图第一次将UI测试添加到应用程序中,并且正在考虑使用espresso。

该应用程序使用Dagger2 for DI并带有@Inject批注的可注入类,并在屏幕(活动/片段)中使用AndroidInjection / AndroidSupportInjection

class Application : android.app.Application(), HasActivityInjector, HasServiceInjector {
...
    override fun onCreate() {
        super.onCreate()
        initDagger()
        Timber.d("Application initialized successfully!")
    }

    protected open fun initDagger() {
        Components.initialize(this)
    }
}

object Components : ComponentFactory {
    private lateinit var sComponent: AppComponent

    fun initialize(app: Application) {
         sAppComponent = DaggerAppComponent.builder()
            .applicationModule(ApplicationModule(this))
            .build()
    }
    // overrides
}

interface ComponentFactory {
    fun app(): AppComponent
    fun authenticated(): AuthenticatedComponent
}

接下来是ComponentModuleAppActivitiesModuleAuthenticatedActivitiesModule是带有@ContributesAndroidInjector的屏幕类。

@Singleton
@Component(modules = [AppModule::class, AppActivitiesModule::class, AndroidInjectionModule::class, AndroidSupportInjectionModule::class])
interface AppComponent {

    fun authenticatedComponentBuilder(): AuthenticatedComponent.Builder

    fun inject(app: Application)

    @Component.Builder
    interface Builder {
        fun build(): AppComponent

        fun applicationModule(applicationModule: ApplicationModule): Builder
    }
}

@Module
open class AppModule(private val application: Application) {
// some @Provides
}
@AuthenticatedScope
@Subcomponent(modules = [AuthenticatedModule::class, AuthenticatedActivitiesModule::class])
interface AuthenticatedComponent {

    fun inject(application: Application)

    @Subcomponent.Builder
    interface Builder {
        fun userModule(module: UserModule): Builder

        fun build(): AuthenticatedComponent
    }
}


@Module
class AuthenticatedModule(private val userId: Long,
                          private val userRole: User.Role) {
// Some @Provides @AuthenticatedScope
}

典型的用例是:

@Singleton
class AppLevelService 
@Inject constructor(...) { ... }

@AuthenticatedScope
class AuthenticatedLevelServices 
@Inject constructor(...) { ... }

class ViewModel 
@Inject constructor(private val appService: AppLevelService,
                    private val authService: AuthenticatedLevelServices) { ... }

class MyActivity : BaseActivity {
    @Inject 
    lateinit var vmProvider: Provide<ViewModel>

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
    }
}

如何为这种“类型”的匕首用法进行测试设置?

我找到了很多使用dagger2进行测试的示例,但使用了@Provides注释,并且我认为应该有一种使用@Inject来模拟可注入类的方法。

我尝试过DaggerMock,但得到了:

  

您必须使用@Provides注释方法而不是@Inject注释来定义覆盖的对象

并不是说它会影响任何东西,但我还将DexOpener与自定义Runner一起使用。

是否有任何想法或好的文档/示例来测试此设置?

0 个答案:

没有答案