Home > OS >  Android unit testing for flow with emitAll
Android unit testing for flow with emitAll

Time:06-14

I have a function that return flow by emitAll

 fun handle(actions: MoviesActions): Flow<MoviesStates> = flow {
    when (actions) {
        is MoviesActions.LoadMovies -> {
            emit(MoviesStates.Loading)
            emitAll(moviesUseCase.execute())
        }
    }
}

And this the use case function

suspend fun execute(): Flow<MoviesStates> = flow {
    combine(f1, f2) { state1: MoviesStates, state2: MoviesStates ->
     
          // some code
        
    }.collect {
        emit(it)
    }
}

No problem in testing the first emission MoviesStates.Loading, the problem is when I try to test the flow which return from usecase by emitAll emitAll(moviesUseCase.execute()), the test fails and I got this result

java.util.NoSuchElementException: Expected at least one element

this is my unit test

@Test
fun testLoadMovies() = runBlocking {
    whenever(useCase.execute()).thenReturn(flow {
        MoviesStates.EmptyList
    })

    val actual = viewModel.handle(MoviesActions.LoadMovies).drop(1).first()
    val expected = MoviesStates.EmptyList

    assertEquals(actual, expected)
}

So How can I test it correctly?

CodePudding user response:

Thanks to gpunto , this is the solution he suggested

@Test
fun testLoadMovies() = runBlocking {
    whenever(useCase.execute()).thenReturn(flow {
         MoviesStates.EmptyList
    })

    useCase.execute().collect { states ->
        val actual = viewModel.handle(MoviesActions.LoadMovies).drop(1).first()
        val expected = states 
        assertEquals(expected, actual)
    }
}
  • Related