0

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

Behnam Maboudi
  • 655
  • 5
  • 21

0 Answers0