android - 在 init 块中使用 postValue 时的 LiveData 单元测试错误
问题描述
我正在尝试使用实时数据为视图模型编写单元测试。
登录视图模型.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
使用实时数据时提供执行上下文,但是在初始化 -block 中的实时数据时它不起作用init
。省略init
-block 时,它可以按需要工作,但我需要初始化实时数据变量的可能性。
在单元测试视图模型时,有什么方法可以使实时数据初始化工作?
解决方案
我设法使用提到的 rula -对我ViewModel
的使用进行了单元测试。但在我的情况下,规则 val 声明有点不同:LiveData
InstantTaskExecutorRule
@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 块也被调用得太早了。也许在方法中创建它是合理的@Before
?喜欢:
private lateinit var viewModel: LoginViewModel
@Before
@Throws(Exception::class)
fun prepare() {
loginViewModel = LoginViewModel(context)
}
推荐阅读
- windows - 在 Windows 上使用介子和 MSYS2 构建 GTK3 失败
- python-3.x - OpenCV-进程在 MAC 上以退出代码 139(被信号 11:SIGSEGV 中断)完成
- python - Jetbot:找不到伺服串行模块(python)
- python - 从 chrome 浏览器的网络面板获取数据
- javascript - 如何在异步继续之前等待查询者的回答被处理(通过 fs.writeFile)
- javascript - 渲染 ejs 文件客户端
- javascript - 如何使用顶级 await 方法处理 const 值的动态导入
- html - 模态叠加问题
- python-3.x - 将视频从一台设备播放到另一台设备
- bootstrap-4 - 仅将 Bootstrap 用于响应功能并删除其他文件