android - 如何对LiveData转换进行单元测试

标签 android unit-testing kotlin android-livedata mockk

我显然不明白如何在Transformation中对业务逻辑进行单元测试。在我的特定情况下,我需要测试Transformations.map,但是我猜Transformations.switchmap会是相同的。

以下仅是我的场景以及我想要实现的示例。

MyViewModel.kt

class MyViewModel: ViewModel() {

private val _sampleLiveDataIwannaTest : MutableLiveData<Int> = MutableLiveData()
val sampleLiveDataIWannaTest: Livedata<Int> = _sampleLiveDataIWannaTest

// ...

val liveDataImNotInterestedIn = Transformations.map(myRepository.streamingData){ 
     streaming->

      _sampleLiveDataIwannaTest.postValue(streaming.firstElementValue +streaming.lastElementValue)

      streaming
  }
// ...
}

带有:
val liveDataImNotInteresedIn : LiveData<Foo>

myRepository.streamingData : LiveData<Foo>
myRepository.streamingData是一个数据源,它会唤醒Transformations.map,进而启动我感兴趣的业务逻辑(_sampleLiveDataIwannaTest中发布的值)。在此特定测试中,我什么都不关心。

MyViewModelTest.kt
class MyViewModelTest {
    @get:Rule    val rule = InstantTaskExecutorRule()

    @RelaxedMockK
    lateinit var myRepository : MyRepository

    @OverrideMockKs
    lateinit var sut: MyViewModel

    @Before
    fun setUp() {
        MockKAnnotations.init(this, relaxUnitFun = true)
    }

    @Test
    fun Transformations_Test(){

        sut.liveDataImNotInterestedIn.observeForever{}

      // 1)I really don't know how to mock the livedata that returns from 
      //     myRepository.streamingData . Something like this is correct?
      //        every{myRepository.streamingData}.returns{< LiveData of type Int > }

     // 2) I wish to write this kind of test: 
     //
     // assertEquals(5, sampleLiveDataIWannaTest.value)

    }

我使用的是MockK而不是Mockito。

最佳答案

单元测试代码将如下所示:

class MyViewModelTest {
@get:Rule
val rule = InstantTaskExecutorRule()

@RelaxedMockK
lateinit var myRepository : MyRepository

@RelaxedMockK
lateinit var mockedSampleLiveDataIWannaTest : Observer<Int>

@OverrideMockKs
lateinit var sut: MyViewModel


@Before
fun setUp() {
    MockKAnnotations.init(this, relaxUnitFun = true)
}


@Test
fun Transformations_Test(){
    val expected = (*YOUR EXPECTED DATA HERE FROM REPOSITORY*)

    every { myRepository.streamingData() } answers { expected }
    sut.sampleLiveDataIWannaTest.observeForever(mockedSampleLiveDataIWannaTest)

    verify { myRepository.streamingData() }
    verify() { mockedSampleLiveDataIWannaTest.onChanged(Int) }
    confirmVerified(myRepository, mockedSampleLiveDataIWannaTest)

}

如果您的存储库使用协程,则将every更改为coEvery,将verify更改为coVerify
了解有关MockK的更多信息:https://mockk.io/

关于android - 如何对LiveData转换进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59987761/

相关文章:

带有 Dagger 2 的 Android 普通 Junit

android - 对象已收集无法评估 ContentValues.values.tostring()

java - 如何有效地使用静态变量?

android - 查询一个文件的信息android

java - Java+kotlin项目中moshi的正确使用方法

java - 从 java 调用带有参数作为密封类的 Kotlin 函数

php - Zend Framework 中的单元测试 json 输出

asp.net-mvc - 这仍然是使用需要 HttpRequest 和 HttpResponse 的 API 进行单元测试的推荐方法吗?

java - 我的测试正确吗?

spring-boot - 如何使用测试容器将 selenium 容器连接到 localhost 网络?