Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

169
Vistas
How do I test a viewModelScope controlled SharedFlow?

I have a SharedFlow. When the ViewModel is created, I change the value to Val1. After that, I use the viewModelScope to make some fake delay of 3 seconds and then change the value to Val2.

class MyViewModel : ViewModel() {

    val x = MutableSharedFlow<String>()

    init {
        x.tryEmit("Val1")
        viewModelScope.launch {
            delay(3000)
            x.tryEmit("Val2")
        }
    }
}

Question

  1. How do I test the initial value is Val1?
  2. How do I test if the value has changed to Val2 after delay?
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

I found the solution:

It's as simple as setting the Main dispatcher to TestCoroutineDispatcher.

@ExperimentalCoroutinesApi
class CoroutineMainExtension : BeforeEachCallback, AfterEachCallback {
    val dispatcher = TestCoroutineDispatcher()
    override fun beforeEach(context: ExtensionContext?) {
        Dispatchers.setMain(dispatcher)
    }

    override fun afterEach(context: ExtensionContext?) {
        Dispatchers.resetMain()
        dispatcher.cleanupTestCoroutines()
    }
}

and use it like this:

@ExtendWith(CoroutineMainExtension::class)

over 4 years ago · Santiago Trujillo Denunciar

0

To test it, you need a way to inject your testing context. It is typically done by setting it as Dispatchers.Main.

Then the easy path is to use MutableStateFlow instead of MutableSharedFlow. Here is an example:

class MyViewModel : ViewModel() {

    val x = MutableStateFlow("Val1")

    init {
        viewModelScope.launch {
            delay(3000)
            x.tryEmit("Val2")
        }
    }
}

class MyViewModelTests {
    private val testDispatcher = TestCoroutineDispatcher()

    @Before
    fun setUp() {
        Dispatchers.setMain(testDispatcher)
    }

    @Test
    fun test() = runBlocking {
        // given
        val myViewModel = MyViewModel()

        // then
        assertEquals("Val1", myViewModel.x.value)

        // when
        testDispatcher.advanceTimeBy(3000)

        // then
        assertEquals("Val2", myViewModel.x.value)
    }
}

If you want to test MutableSharedFlow, you should better move your logic from the constructor to some function, like onCreate. Then you should collect and observe how your values change. Here is an example (we could make a better one with some testing library like Turbine):

class MyViewModel : ViewModel() {

    val x = MutableSharedFlow<String>()

     fun onCreate() {
        viewModelScope.launch {
            x.emit("Val1")
            delay(3000)
            x.emit("Val2")
        }
    }
}

class MyViewModelTests {
    private val testDispatcher = TestCoroutineDispatcher()

    @Before
    fun setUp() {
        Dispatchers.setMain(testDispatcher)
    }

    @Test
    fun test() = runBlocking {
        // given
        val myViewModel = MyViewModel()
        var xChangeHistory = mapOf<Long, String>()
        myViewModel.viewModelScope.launch {
            myViewModel.x.collect {
                xChangeHistory += testDispatcher.currentTime to it
            }
        }

        // then
        myViewModel.onCreate()
        testDispatcher.advanceUntilIdle()

        // then
        assertEquals(mapOf(0L to "Val1", 3000L to "Val2"), xChangeHistory)
    }
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda