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

使用Dagger2、Espresso和Mockito对MVVM架构进行Android UI测试,android,mockito,dagger-2,android-espresso,dagger,Android,Mockito,Dagger 2,Android Espresso,Dagger,我第一次尝试在应用程序中添加UI测试,当时我正在考虑使用浓缩咖啡 该应用程序使用Dagger2 for DI,对应该可注入的类使用@Inject注释,并在屏幕(活动/片段)中使用AndroidInjection/AndroidSupportInjection 接下来是组件s和模块s。AppActivitiesModule和AuthenticatedActivitiesModule是屏幕上带有@ContributesAndroidInjector的类 @Singleton @Component(m

我第一次尝试在应用程序中添加UI测试,当时我正在考虑使用浓缩咖啡

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

接下来是
组件
s和
模块
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
}
一个典型的用例是:

@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)
    }
}
@Singleton
类AppLevelService
@注入构造函数(…){…}
@认证范围
类AuthenticatedLevelServices
@注入构造函数(…){…}
类视图模型
@注入构造函数(私有值appService:AppLevelService,
私有val authService:AuthenticatedLevelServices){…}
类MyActivity:BaseActivity{
@注入
lateinit var vmProvider:提供
重写创建时的乐趣(savedInstanceState:Bundle?){
雄激素注射。注射(这个)
}
}
如何为这种“类型”的匕首使用进行测试设置

我发现很多使用dagger2进行测试的例子,但是对于
@提供了
注释,我认为应该有一种方法可以使用
@Inject
模拟可注入类

我试过了
DaggerMock
,但我得到了:

必须使用@Providers注释方法而不是@Inject注释来定义重写的对象

这并不是说它会影响任何东西,但我也在使用带有
DexOpener
的自定义运行程序


测试此设置有什么想法或好的文档/示例吗?

我上周也经历了同样的考验。这确实帮助我模仿
组件
和。我必须扩展
应用程序
类,然后CustomRunner用模拟的应用程序替换实际的应用程序。然后在测试
设置过程中
,用模拟组件替换组件。@Ranjan您能分享代码吗。我正在尝试用浓咖啡测试模拟活动中的视图模型。但我无法提供模拟视图模型。我上周经历了同样的考验。这确实帮助我模仿
组件
和。我必须扩展
应用程序
类,然后CustomRunner用模拟的应用程序替换实际的应用程序。然后在测试
设置过程中
,用模拟组件替换组件。@Ranjan您能分享代码吗。我正在尝试用浓咖啡测试模拟活动中的视图模型。但我无法提供模拟视图模型。
@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)
    }
}