要对此问题提供一些背景知识,我有一个ViewModel,它等待一些数据,将其发布到MutableLiveData,然后通过某些属性公开所有值。这是一个简短的概要:
class QuestionViewModel {
private val state = MutableLiveData<QuestionState>()
private val currentQuestion: Question?
get() = (state.value as? QuestionState.Loaded)?.question
val questionTitle: String
get() = currentQuestion?.title.orEmpty()
...
}
然后,在我的测试中,我模拟数据并仅运行assertEquals检查:
assertEquals("TestTitle", viewModel.questionTitle)
到目前为止,所有这些方法都可以正常工作,但是我实际上希望我的片段在当前问题发生变化时进行观察。因此,我尝试将其更改为使用Transformations.map
:
class QuestionViewModel {
private val state = MutableLiveData<QuestionState>()
private val currentQuestion: LiveData<Question> = Transformations.map(state) {
(it as? QuestionState.Loaded)?.question
}
val questionTitle: String
get() = currentQuestion.value?.title.orEmpty()
...
}
突然,我在测试类中的所有断言都失败了。我公开了currentQuestion
,并在我的单元测试中验证了它的值为null。我确定这是问题所在,因为:
state
LiveData中获取正确的值我已经将InstantTaskExecutorRule
添加到了单元测试中,但是也许不能处理Transformations
方法?
答案 0 :(得分:1)
我最近遇到了同样的问题,我通过向LiveData添加模拟的观察者来解决了这个问题:
@Mock
private lateinit var observer: Observer<Question>
init {
initMocks(this)
}
fun `test using mocked observer`() {
viewModel.currentQuestion.observeForever(observer)
// ***************** Access currentQuestion.value here *****************
viewModel.questionTitle.removeObserver(observer)
}
fun `test using empty observer`() {
viewModel.currentQuestion.observeForever {}
// ***************** Access currentQuestion.value here *****************
}
不确定其工作原理,或者不确定测试后不删除空观察者的后果。
此外,请确保导入正确的Observer类。如果您使用的是AndroidX:
import androidx.lifecycle.Observer
答案 1 :(得分:0)
好像您在it变量上缺少.value
。
private val currentQuestion: LiveData<Question> = Transformations.map(state) {
(it.value as? QuestionState.Loaded)?.question
}
答案 2 :(得分:0)
Luciano是正确的,这是因为未观察到LiveData。这是一个Kotlin实用程序类,可以帮助您解决这个问题。
class LiveDataObserver<T>(private val liveData: LiveData<T>): Closeable {
private val observer: Observer<T> = mock()
init {
liveData.observeForever(observer)
}
override fun close() {
liveData.removeObserver(observer)
}
}
// to use:
LiveDataObserver(unit.someLiveData).use {
assertFalse(unit.someLiveData.value!!)
}