-
Notifications
You must be signed in to change notification settings - Fork 1.9k
kotlinx-coroutines-test:1.6.1- Issue with collecting values of StateFlow in tests #3367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think I've got the same issue. In my case it looks like a problem with 'runTest' function. Please take a look at the code below:
Both functions are basically the same and should send four emissions to the state flow (emissions: 0, 1, 2, 3). The only difference is, that in the first case I use deprecated function 'runBlockingTest' (it works correctly), and in the second case I use new 'runTest' function (it fails, it sends only emissions: 0, 3). It would be greatly appreciated if this could be improved in 'runTest'. @Subuday, maybe for now you could use 'runBlockingTest' as a workaround. |
@tom2048 what if after |
@mhernand40, adding |
@tom2048 Understood. You definitely do not want to put If the tests need to assert all the values emitted by the |
@mhernand40, @dkhalanskyjb thanks for your answers. Indeed you're right about conflating successive emissions. However there are some cases to be tested which are not processed as successive while running an application but become successive during unit test. Please see the following code:
The ViewModel above is an example of preloader visibility logic while loading data on the screen. While running the application state changes are processed after the delay and therefore are treated as separate emissions. |
Thanks
3 Mar 2023 Cum 20:36 tarihinde tom2048 ***@***.***> şunu
yazdı:
… @mhernand40 <https://github.com/mhernand40>, @dkhalanskyjb
<https://github.com/dkhalanskyjb> thanks for your answers. Indeed you're
right about conflating successive emissions. However there are some cases
to be tested which are not processed as successive while running an
application but become successive during unit test. Please see the
following code:
package com.exampleapp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
class PreloaderExampleViewModel(private val useCase: () -> Flow<Unit>) : ViewModel() {
private val _uiState = MutableStateFlow(UiState(false))
val uiState: StateFlow<UiState> = _uiState
fun loadData() {
viewModelScope.launch {
useCase.invoke()
.onStart { _uiState.value = _uiState.value.copy(preloader = true) }
.catch { _uiState.value = _uiState.value.copy(preloader = false) }
.collect {
_uiState.value = _uiState.value.copy(preloader = false)
}
}
}
data class UiState(
val preloader: Boolean
// other state properties
// ...
)
}
The ViewModel above is an example of preloader visibility logic while
loading data on the screen. While running the application state changes are
processed after the delay and therefore are treated as separate emissions.
On the other hand in unit test useCase can be mocked as simple
flowOf(Unit) and then the emissions are conflated so the behavior is
different. Would you suggest proper approach to handle such cases?
—
Reply to this email directly, view it on GitHub
<#3367 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A3WKLSCFHC5BIQ2DEBANSLLW2IT3VANCNFSM53THNFVA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
The solution with mocking
I guess |
good job |
The master issue for this topic is now #3939, closing this one in its favor. |
There are collected only the first and the last values. It's an Android application.
mainDispatcherRule
is used to replaceDispatcher.Main
->UnconfinedTestDispatcher
. The idea is to collect all emitted values fromStateFlow
. But the intermediate values are skipped. I can not grab the problem. I've referenced to this implementationThe text was updated successfully, but these errors were encountered: