首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在单元测试中从`Transformations.map`访问值

无法在单元测试中从`Transformations.map`访问值
EN

Stack Overflow用户
提问于 2019-05-29 13:53:16
回答 3查看 1K关注 0票数 2

为了给这个问题提供一些背景,我有一个ViewModel,它等待一些数据,将其发布到MutableLiveData,然后通过一些属性公开所有的值。这是一个简短的要点,它看起来是什么样子:

代码语言:javascript
复制
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检查:

代码语言:javascript
复制
assertEquals("TestTitle", viewModel.questionTitle)

到目前为止,所有这些都很好,但我实际上希望我的片段能够在当前问题发生变化时进行观察。因此,我尝试将其改为使用Transformations.map

代码语言:javascript
复制
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,并在我的单元测试中验证了它的值为空。我认为这是个问题,因为:

  • 我可以模拟数据,仍然可以从我的state LiveData中获得正确的值。
  • 我可以运行我的应用程序并在屏幕上看到预期的数据,所以这个问题是针对我的单元测试的。

我已经将InstantTaskExecutorRule添加到我的单元测试中了,但是也许这并不能处理Transformations方法?

EN

回答 3

Stack Overflow用户

发布于 2019-07-17 18:48:23

最近,我遇到了同样的问题,我通过在LiveData中添加一个模拟的观察者来解决这个问题:

代码语言:javascript
复制
 @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 *****************
 }

不确定它究竟是如何工作的,也不确定不移除空观察者的后果。

另外,确保导入正确的观察者类。如果您使用的是AndroidX:

代码语言:javascript
复制
import androidx.lifecycle.Observer
票数 4
EN

Stack Overflow用户

发布于 2019-09-04 03:43:00

卢西亚诺是正确的,这是因为LiveData没有被观察到。这里有一个Kotlin实用程序类来帮助解决这个问题。

代码语言:javascript
复制
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!!)
}
票数 1
EN

Stack Overflow用户

发布于 2019-05-29 16:46:59

看起来,您缺少it变量上的.value

代码语言:javascript
复制
private val currentQuestion: LiveData<Question> = Transformations.map(state) {
        (it.value as? QuestionState.Loaded)?.question
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56362246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档