android - 使用 Dagger2、Espresso 和 Mockito 对 MVVM 架构进行 Android UI 测试
问题描述
我第一次尝试将 UI 测试添加到应用程序中,我正在考虑使用 espresso。
该应用程序将 Dagger2 用于 DI,并@Inject
为应该可注入的类和AndroidInjection
/AndroidSupportInjection
在屏幕中(Activity / Fragment)添加注释。
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
}
接下来是Component
s 和Module
s。AppActivitiesModule
和AuthenticatedActivitiesModule
是@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
.
用于测试此设置的任何想法或好的文档/示例?