我在ViewModel中有一个函数,有两个状态,第一个状态总是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
的多个值?
6条答案
按热度按时间lndjwyie1#
使用***mockk***可以捕获值并将其存储在列表中,然后按顺序检查值。
5vf7fwbs2#
我假设您正在使用mockk库
1.首先,您需要创建观察者对象
1.使用上一个观察者对象观察您的实时数据
1.调用getPostWithSuspend()函数
1.核实一下
relj7zay3#
wfypjpf44#
我为
LiveData
编写了自己的RxJava风格测试观察器并将其用作
soat7uwm5#
嗨,你可以简单地解决这个问题,修改扩展名一点点.它是这样的:
要点是,您需要先增加锁存器计数,然后在锁存器倒计时到零之前不要删除观察器。
剩下的就很简单了,你只需要把你的结果存储在一个列表中。
祝你好运!
9vw9lbht6#
替代你可以使用mockito-kotlin