我正在尝试使用实时数据为 View 模型编写单元测试。
LoginViewModel.kt
class LoginViewModel @Inject constructor(
val context: Context
): ViewModel() {
val username = MutableLiveData<String>()
val password = MutableLiveData<String>()
val isLoginButtonEnabled = MediatorLiveData<Boolean>().apply {
fun combineLatest(): Boolean {
return !(username.value.isNullOrEmpty() || password.value.isNullOrEmpty())
}
addSource(username) { this.value = combineLatest() }
addSource(password) { this.value = combineLatest() }
}
init {
username.postValue("test")
password.postValue("test")
}
}
LoginViewModelTest.kt
@RunWith(MockitoJUnitRunner::class)
class LoginViewModelTest {
@Rule
@JvmField
val instantTaskExecutorRole = InstantTaskExecutorRule()
private val context = mock(Context::class.java)
private val loginViewModel = LoginViewModel(context)
@Test
fun loginButtonDisabledOnEmptyUsername() {
val observer = mock<Observer<Boolean>>()
loginViewModel.isLoginButtonEnabled.observeForever(observer)
loginViewModel.username.postValue("")
verify(observer).onChanged(false)
}
}
我的单元测试在 username.postValue("test")
行抛出以下异常:
java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
InstantTaskExecutorRule
应该在使用实时数据时提供执行上下文,但是在 init
block 中初始化实时数据时它不起作用。当省略 init
block 时,它会按预期工作,但我需要初始化实时数据变量的可能性。
在对 View 模型进行单元测试时,有什么方法可以使实时数据初始化工作吗?
最佳答案
我设法使用提到的规则 - InstantTaskExecutorRule
对使用 LiveData
的 ViewModel
进行了单元测试。但在我的例子中,规则 val 声明有点不同:
@Suppress("unused")
@get:Rule
val instantTaskExecutorRule: InstantTaskExecutorRule = InstantTaskExecutorRule()
编辑:
@Before
@Throws(Exception::class)
fun prepare() {
MockitoAnnotations.initMocks(this)
}
编辑2:
出于某些奇怪的原因,我无法重现它:) 另外,我认为问题可能出在您初始化 ViewModel 的方式上——
private val loginViewModel = LoginViewModel(context)
我假设它初始化得太早了,因此它的 init block 也被调用得太早了。也许在 @Before
方法中创建它是合理的?喜欢:
private lateinit var viewModel: LoginViewModel
@Before
@Throws(Exception::class)
fun prepare() {
loginViewModel = LoginViewModel(context)
}
关于android - 在 init block 中使用 postValue 时出现 LiveData 单元测试错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52762418/