gpt4 book ai didi

android - 使用 LiveData、协程和 MockK 测试多个 View 状态的 ViewModel 单元

转载 作者:行者123 更新时间:2023-12-03 15:21:03 26 4
gpt4 key购买 nike

我在 ViewModel 中有一个具有 2 个状态的函数,第一个状态始终是 LOADING,第二个状态取决于 api 或 db 交互的结果。
这是功能

fun getPostWithSuspend() {

myCoroutineScope.launch {

// Set current state to LOADING
_postStateWithSuspend.value = ViewState(LOADING)

val result = postsUseCase.getPosts()

// Check and assign result to UI
val resultViewState = if (result.status == SUCCESS) {
ViewState(SUCCESS, data = result.data?.get(0)?.title)
} else {
ViewState(ERROR, error = result.error)
}

_postStateWithSuspend.value = resultViewState
}
}
并且没有错误,测试可以很好地检查错误或成功的最终结果
   @Test
fun `Given DataResult Error returned from useCase, should result error`() =
testCoroutineRule.runBlockingTest {

// GIVEN
coEvery {
useCase.getPosts()
} returns DataResult.Error(Exception("Network error occurred."))

// WHEN
viewModel.getPostWithSuspend()

// THEN
val expected = viewModel.postStateWithSuspend.getOrAwaitMultipleValues(dataCount = 2)

// Truth.assertThat("Network error occurred.").isEqualTo(expected?.error?.message)
// Truth.assertThat(expected?.error).isInstanceOf(Exception::class.java)
coVerify(atMost = 1) { useCase.getPosts() }
}
但我找不到方法来测试 LOADING状态是否发生,所以我将现有的扩展功能修改为
fun <T> LiveData<T>.getOrAwaitMultipleValues(
time: Long = 2,
dataCount: Int = 1,
timeUnit: TimeUnit = TimeUnit.SECONDS,
afterObserve: () -> Unit = {}
): List<T?> {

val data = mutableListOf<T?>()
val latch = CountDownLatch(dataCount)

val observer = object : Observer<T> {
override fun onChanged(o: T?) {
data.add(o)
latch.countDown()
this@getOrAwaitMultipleValues.removeObserver(this)
}
}
this.observeForever(observer)

afterObserve.invoke()

// Don't wait indefinitely if the LiveData is not set.
if (!latch.await(time, timeUnit)) {
this.removeObserver(observer)
throw TimeoutException("LiveData value was never set.")
}

@Suppress("UNCHECKED_CAST")
return data.toList()
}
在 LiveData 更改时将数据添加到列表中并将状态存储在该列表中,但
它永远不会返回 LOADING 状态,因为它发生在观察开始之前。有没有办法测试 LiveData 的多个值? ?

最佳答案

使用 模拟 您可以捕获值并将其存储在列表中,然后按顺序检查值。

    //create mockk object
val observer = mockk<Observer<AnyObject>>()

//create slot
val slot = slot<AnyObject>()

//create list to store values
val list = arrayListOf<AnyObject>()

//start observing
viewModel.postStateWithSuspend.observeForever(observer)


//capture value on every call
every { observer.onChanged(capture(slot)) } answers {

//store captured value
list.add(slot.captured)
}

viewModel.getPostWithSuspend()

//assert your values here

关于android - 使用 LiveData、协程和 MockK 测试多个 View 状态的 ViewModel 单元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63339306/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com