Freesko
Freesko

Reputation: 113

Unit testing coroutine StateFlow

I am trying to test this StateFlow which lives in a ViewModel and receives data from a UseCase.

val data: StateFlow<Data> = getDataUseCase.execute(Unit).stateIn(viewModelScope, Lazily, Data())

I have written this test using Mockk and Turbine

@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `test data updates value`() = runTest {

    val expectedId = 2

    coEvery { getDataUseCase.execute(Unit) } returns flowOf(Data(id = expectedId))

    viewModel.data.test {
        assertEquals(expectedId, expectMostRecentItem().id)
    }

}

I am always receiving a Data object with all its fields to null so all my assertions are failing (even if I throw an Exception).

Any ideas? thanks!

Upvotes: 1

Views: 942

Answers (1)

Izadi Egizabal
Izadi Egizabal

Reputation: 806

I think you might need to collect the state in order to activate and start consuming the underlying flow as stated in the docs.

In your case you could try with:

@Test
fun `test data updates value`() = runTest {

    val expectedId = 2

    coEvery { getDataUseCase.execute(Unit) } returns flowOf(Data(id = expectedId))

    // create an empty collector for the StateFlow
    backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
        viewModel.data.collect()
    }

    viewModel.data.test {
        assertEquals(expectedId, expectMostRecentItem().id)
    }

}

Upvotes: 1

Related Questions