gpt4 book ai didi

android - 在 init block 中使用 postValue 时出现 LiveData 单元测试错误

转载 作者:太空宇宙 更新时间:2023-11-03 13:08:07 26 4
gpt4 key购买 nike

我正在尝试使用实时数据为 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 对使用 LiveDataViewModel 进行了单元测试。但在我的例子中,规则 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com