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())
}
}
这是否足够好,或者我是否应该在单元测试中注意到这里发生了其他事情--对网络的异步调用--我是否应该测试它?如果这个问题的答案是“是”,是否有一种方法可以在不模拟数据源的情况下进行单元测试(考虑到现在的最佳实践越来越倾向于在模拟上伪造)?
1条答案
按热度按时间rkue9o1l1#
你想测试的是
getSomething
函数中的一个副作用,如果你想测试它(这取决于你想把测试代码和实现代码耦合在一起的程度),你可以做以下事情:FakeDataSource
中定义一些状态;你可以在第一次使用布尔值defaultfalse
。fetchSomethingAsync
时,您可以更新该状态的值,例如,将其更新为true
。fakeDataSource.isContentFetched()
是否为true,这基本上读取了我们定义的值。你也可以使用mock,但是正如你所说的,最好是朝着fake的方向发展,因为我可以在另一个测试相同行为的测试中使用相同的fake;否则,如果我使用模拟,我必须重新定义每个测试中的验证逻辑。