Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

168
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda