微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android:LiveData 和 Flow 的单元测试

如何解决Android:LiveData 和 Flow 的单元测试

我正在尝试为我的 viewmodel 编写单元测试,但我不知道如何处理 LiveData 函数

特别是我无法验证接收 LiveData Observer 的所有值。

关于我有一个发出值然后作为 LiveData 传递的 Flow 用例,测试 operation 函数的最佳方法是什么?

在下面的代码中,您会发现我只能读取值 "endLoading",但我想检查所有值:"startLoading""Hello Dummy $input"、{{1 }}

Mainviewmodel.kt

"endLoading"

MainviewmodelTest.kt

class Mainviewmodel(val useCase: DummyUseCase = DummyUseCase()): viewmodel() {
    fun operation(value: Int): LiveData<String> = useCase.invoke(value)
        .transform { response ->
            emit(response)
        }.onStart {
            emit("startLoading")
        }.catch {
            emit("ERROR")
        }.onCompletion {
            emit("endLoading")
        }.asLiveData(viewmodelScope.coroutineContext)
}

解决方法

您可以使用自定义 Observer<T> 实现测试 LiveData。创建一个观察者,记录所有发出的值,并让您对历史进行断言。

记录值的观察者可能如下所示:

class TestableObserver<T> : Observer<T> {
    private val history: MutableList<T> = mutableListOf()

    override fun onChanged(value: T) {
        history.add(value)
    }

    fun assertAllEmitted(values: List<T>) {
        assertEquals(values.count(),history.count())

        history.forEachIndexed { index,t ->
            assertEquals(values[index],t)
        }
    }
}

您可以使用 assertAllEmitted(...) 函数断言所有给定的值是否都是由 LiveData 发出的。

测试函数将使用 TestableObserver 类的实例而不是模拟的实例:

@Test // AAA testing
fun `when my flow succeeds,return a state String`() {
    runBlocking {
        //Arrange
        val stateObserver = TestableObserver<String>()

        val input = 10
        coEvery { useCase.invoke(input) }.returns(flow {
            emit("Hello Dummy $input")
        })

        //Act
        val actual = viewModel.operation(input).apply {
            observeForever(stateObserver)
        }

        //Assert
        stateObserver.assertAllEmitted(
            listOf(
                "startLoading","Hello Dummy 10","endLoading"
            )
        )
    }
}

使用模拟框架和断言框架可以断言 LiveData 的历史,但是,我认为实现这个可测试的观察器更具可读性。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。