kotlin 如何(以及应该)验证在状态单元测试中调用了异步内部方法?

xnifntxz  于 2023-03-30  发布在  Kotlin
关注(0)|答案(1)|浏览(164)
override fun getSomething(): LiveData<List<Content>> {
        fakeDataSource.fetchSomethingAsync()
        return contentDao.getSomething()
    }

这里我们有一个repository方法来远程获取一些数据,同时从一个Room数据库返回一些livedata。在repository中调用这个方法的viewmodel并不关心repository是从幕后的网络获取数据-它只知道它正在获取一些livedata并监视它的变化。
现在我必须对这个方法进行单元测试。基于状态的单元测试说,我所关心的只是调用后系统的状态(而行为单元测试绝对需要我验证异步调用)。在这里,另一个类(fakeDataSource)在稍后的某个时间异步更改状态的事实在这个特定方法(?)的单元测试上下文中应该与我无关。
所以我从我的假刀中返回了一个假物品,我的测试看起来像:

@Test
    fun getSomething_returnsLocal() {
        val result: LiveData<List<Content>> = testedContentRepository.getSomething()
        result.value?.let {
            assert(it.isNotEmpty())
        }
    }

这是否足够好,或者我是否应该在单元测试中注意到这里发生了其他事情--对网络的异步调用--我是否应该测试它?如果这个问题的答案是“是”,是否有一种方法可以在不模拟数据源的情况下进行单元测试(考虑到现在的最佳实践越来越倾向于在模拟上伪造)?

rkue9o1l

rkue9o1l1#

你想测试的是getSomething函数中的一个副作用,如果你想测试它(这取决于你想把测试代码和实现代码耦合在一起的程度),你可以做以下事情:

  • FakeDataSource中定义一些状态;你可以在第一次使用布尔值default false
  • 然后,当您的方法被调用fetchSomethingAsync时,您可以更新该状态的值,例如,将其更新为true
  • 然后,您可以AssertfakeDataSource.isContentFetched()是否为true,这基本上读取了我们定义的值。

你也可以使用mock,但是正如你所说的,最好是朝着fake的方向发展,因为我可以在另一个测试相同行为的测试中使用相同的fake;否则,如果我使用模拟,我必须重新定义每个测试中的验证逻辑。

相关问题