I have a simple viewModel:
class myViewModel: ViewModel() {
val someStringStateFlow = MutableStateFlow<String>("")
fun doSomething() {
viewModelScope.launch(DispatcherProvider.Main) {
delay(200)
someStringStateFlow.emit("Updated")
}
}
}
I have a test class:
class SearchViewModelTest : BehaviorSpec({
Dispatchers.setMain(DispatcherProvider(true).Main)
var viewModel = myViewModel()
Given("the view model is initialized") {
runTest {
When("call doSomeThing") {
viewModel.doSomething()
advanceUntilIdle()
advanceTimeBy(5000)
runCurrent()
Then("The stateflow should be updated") {
viewModel.someStringStateFlow.value shouldBe "Updated"
}
}
}
}
DispatcherProvider provides real or test dispatcher:
object DispatcherProvider {
private var isTest: Boolean? = null
operator fun invoke(isTest: Boolean? = null): DispatcherProvider {
this.isTest = isTest
return this
}
val Main: CoroutineDispatcher
get() = getTestDispatcher(isTest) ?: Dispatchers.Main
private fun getTestDispatcher(isTest: Boolean?): CoroutineDispatcher? =
if (isTest == true) testDispatcher else null
private val testDispatcher: CoroutineDispatcher by lazy {
newSingleThreadContext("Test Dispatcher")
}
}
This test should be successful but it fails. advanceTimeBy doesn't work correctly What is wrong here?
I'm using coroutine version 1.6.4 with the new experimental test framework