我有一个ViewModel
,它使用Flow从存储库中检索数据。当流程开始时,我将本地' loading
' StateFlow
对象设置为true。
我有一个简单的测试,它将一个假的仓库传递给ViewModel
。我在我的ViewModel
上调用' fetchItems
',它调用我的存储库。
我想Assert加载StateFlow
已设置为True,但Assert在流的onStart
函数之前执行。
编辑:我知道流程是异步运行的,我想等到流程启动后再进行Assert
然后,一旦我测试了加载状态被设置为真,我也想设置加载状态被设置为假。
我的视图模型:
class MainViewModel @Inject constructor(private val newsInterface: DataRepositoryInterface ) : ViewModel() {
private val _loading = MutableStateFlow(false)
val loading: StateFlow<Boolean>
get() = _loading.asStateFlow()
fun fetchItems(){
viewModelScope.launch {
newsInterface.getStories()
.flowOn(Dispatchers.IO)
.onStart { _loading.update {true } // Loading has started
.collect { items ->
_loading.update { false } //Loading has finished
}
}
}
}
我的测试:
@RunWith(JUnit4::class)
class GameUITest {
lateinit var viewModel: MainViewModel
@Before
fun init() {
viewModel = MainViewModel(FakeNetwork())
}
@Test
fun testViewModel() {
viewModel.fetchItems()
assert(viewModel.loading.value == true) // Assertion fails as loading has not been set yet
}
}
Fake repository:
class FakeNetwork @Inject constructor() : DataRepositoryInterface {
override fun getStories(): Flow<List<Int>> {
return flow {
//Do stuff
emit(listOf(1, 2, 3))
}
}
}
1条答案
按热度按时间zmeyuzjn1#
我想出了这个方法。
完整文件here
这里发生的事情是,我观察
StateFlow
发出的值,然后检查发出了什么值。我使用backgroundScope
是因为StateFlow
上的.toCollection
调用永远不会完成,它的协程也永远不会完成-这会导致测试失败。但是backgroundScope
可以帮助关闭if for test(:这与通常用于TestSubscriber
的Rx测试的方法类似,也可以访问所有发出的值。也发现Google有点建议同样的方法。实际上,我从那个页面得到了一个背景范围的想法(: