手柄视图模型注入到仪器测试中 [英] Hilt viewmodel injection into instrumentation tests
本文介绍了手柄视图模型注入到仪器测试中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我一直在搜索如何将ViewModel注入测试中,以便我可以对其进行测试。假设视图模型有一个带有某个业务逻辑交互程序的构造函数注入。我可以很容易地将它注射到碎片中,但在测试中没有成功。
@HiltAndroidTest
class ViewModelTest
val randomViewmodel: RandomViewmodel// now what ? since by viewModels() is not accessible in tests
@Test
fun viewModelTet() {
randomViewmodel.triggerAction()
assertEquals(RandomVIewState(1), randomViewmodel.getState())
}
我尝试在测试类中实现byViewModels(),可以在没有构造函数参数的情况下注入视图模型,但没有成功。
class RandomViewmodel @ViewModelInject constructor(
private val randomInteractor: RandomInteractor
) : ViewModel
Caused by: java.lang.InstantiationException: class app.RandomViewModel has no zero argument constructor
原因:我希望能够完全测试我的屏幕逻辑,因为viewModel将处理交互因素等的依赖关系,可能会有相当多的逻辑与各种数据流动在一起。测试片段很可能是可能的,但在包含大量测试的较大对象中要慢得多。
我已经读过https://developer.android.com/jetpack/guide#test-components,它建议在viewModel中进行JUnit测试和模拟依赖项,但然后您必须分别为每个依赖项创建测试,无法真正测试整个屏幕的逻辑
推荐答案
@HiltViewModel
批注生成您原本应该编写的绑定模块。
其中之一是名为BindsModule的模块。 此类在包含该多绑定模块和一个键的包装类中声明。
例如,假设您创建了一个名为MyViewModel
的ViewModel
package com.mypackage
@HiltViewModel
class MyViewModel @Inject constructor(
private val someDependency: MyType
) : ViewModel()
则生成的模块如下所示:
@OriginatingElement(
topLevelClass = MyViewModel.class
)
public final class MyViewModel_HiltModules {
private MyViewModel_HiltModules() {
}
@Module
@InstallIn(ViewModelComponent.class)
public abstract static class BindsModule {
private BindsModule() {
}
@Binds
@IntoMap
@StringKey("com.mypackage.MyViewModel")
@HiltViewModelMap
public abstract ViewModel binds(MyViewModel vm);
}
@Module
@InstallIn(ActivityRetainedComponent.class)
public static final class KeyModule {
private KeyModule() {
}
@Provides
@IntoSet
@HiltViewModelMap.KeySet
public static String provide() {
return "com.mypackage.MyViewModel";
}
}
}
因此,您ViewModel可以替换@Binds
约定,只需在测试类中与实现类型匹配的属性上使用@BindValue
注释,在本例中,它将是MyViewModel
无需卸载与ViewModel相关的任何模块。
@HiltAndroidTest
class MyFragmentInstrumentedUnitTest {
@get:Rule val hiltRule = HiltAndroidRule(this)
// either a subclass or a mock, as long as the types match
// it will provide this instance as the implementation of the abstract binding
// `public abstract ViewModel binds(MyViewModel vm);`
@BindValue
val mockMyViewModel= mock<MyViewModel>()
@Before
fun init() {
hiltRule.inject()
}
}
这篇关于手柄视图模型注入到仪器测试中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文