Как выполнить модульное тестирование трансформации LiveData - PullRequest
0 голосов
/ 30 января 2020

Я явно не понимаю, как тестировать бизнес-логику c внутри Transformation. В моем конкретном случае c мне нужно протестировать 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, который, в свою очередь, запускает бизнес логи c меня интересует (значение указано в _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.

1 Ответ

0 голосов
/ 03 февраля 2020

Код модульного теста будет выглядеть следующим образом:

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/

...