Android: 如何在单元测试中设置私有 MutableLiveData

Android: How to set private MutableLiveData in unit test

我正在尝试通过编写一些单元测试来测试我的 viewmodel。我的问题是,如果不为 MutableLiveData 手动 设置一些值,我将无法实现我的目标(在生产中它们是通过数据绑定设置的)。这里的问题是我的 MutableLiveData 是(显然)private,因此我无法通过在单元测试中编写 mutablelivedata.value = "Some Value" 来设置值。

我读过一些文章,有人说我应该通过编写自定义 setter 公开我的 MutableLiveData,例如:

private val _myMutableLiveData = MutableLiveData<String>()
val myPublicLiveData: LiveData<String> get() = _myMutableLiveData

// setter
fun setStringForLiveData(value: String) {
   _myMutableLiveData.value = value
}

我的问题来了:将 MutableLiveData 设置为 private 但将 setter 与自定义 setStringForLiveData(value: String) 和 getter 与 [= 公开的意义何在? 18=]。我的意思是,当我公开我的 private 字段的 getter 和 setter 时,为什么我不应该让它成为 public?

这是我目前测试 MutableLiveData 的方法(我不知道这是否有意义甚至有效)

@Test
fun `first shipping text should be set correctly`() {
   (viewModel.secondDropDownVisibility as MutableLiveData<Boolean>).value = false
   (viewModel.shippingFirstDdText as MutableLiveData<String>).value = "Toast"
    assertEquals("Toast", viewModel.decideShippingTextOne())
}

我希望有比为每个 mutablelivedata 编写自定义 setter 更好的方法(我有超过 20 个,这只是丑陋的样板代码)。也许我在这里误解了什么。

请记住,我对 Android MVVM 的开发和概念尤其是 Livedata 还比较陌生。

非常感谢您的帮助,谢谢!

如果需要从外部修改 MutableLiveData public,您应该按原样制作它(无需对方法做出任何额外保证)。

如果您一直在使用数据绑定,您将公开 ObservableField,它也是 read/writeable。

private val _myMutableLiveData = MutableLiveData<String>()
val myPublicLiveData: LiveData<String> get() = _myMutableLiveData

// setter
fun setStringForLiveData(value: String) {
   _myMutableLiveData.value = value
}

抱歉,这段代码没有意义。如果您绝对需要这样做,那么就没有必要使用双字段,因为无论如何您都会公开可变状态。

话虽这么说,但我认为您需要求助于此,而且它通常是一种代码味道。我看不到你的整个视图模型,但我假设你有一个 public 函数(或一些初始化代码)触发一些工作并将数据推送到实时数据,而这就是你必须测试的。如果您想上传您的完整视图模型,我可以尝试通过更新答案来建议测试方法。干杯!

好吧,这可能不是最好的答案,但这对我有用。在这一点上,我真的不关心“哦不,但这在 android 编程中是不对的”或“但你不应该在单元测试中那样做”。测试用例有效,这就是我所需要的。

@Test
fun `first shipping text should be set correctly`() {
   (viewModel.secondDropDownVisibility as MutableLiveData<Boolean>).value = false
   (viewModel.shippingFirstDdText as MutableLiveData<String>).value = "Toast"
    assertEquals("Toast", viewModel.decideShippingTextOne())
}

我有两个私有字段 _secondDropDownVisibility_shippingFirstDdText MutableLiveData<T> 类型和两个 public 字段 secondDropDownVisibilityshippingFirstDdText LiveData<T>

干杯