6

I following the new google guide and end with this to represent the state in viewmodel like tis

var uiState: AccountSettingUiState by
    mutableStateOf(AccountSettingUiState.Initial)
        private set

then I have this function

 fun resetPasswordUseCase(context: Context) {
         resetPasswordUseCase.execute(context)
            .subscribeOn(rxSchedulers.io)
            .doOnSubscribe {
               uiState  = AccountSettingUiState.Loading
            }
            .observeOn(rxSchedulers.ui)
            .subscribe {
               uiState  = AccountSettingUiState.Result

  }
}

I want to test this function by assert emitting loading then result but how I can capture the values

epool
  • 6,710
  • 7
  • 38
  • 43
ASA
  • 371
  • 1
  • 3
  • 11

1 Answers1

2

I can test only final state

ViewModel

@HiltViewModel
class SearchViewModel @Inject constructor(
    private val searchItemUseCase: SearchItemUseCase,
    private val searchUIMapper: SearchUIMapper
) : ViewModel() {

    var search by mutableStateOf<StateUI<SearchUI>>(StateUI.Init())

    fun searchItem(query: String) {
        viewModelScope.launch {
            search = StateUI.Loading()
            searchItemUseCase.execute(query)
                .catch { error ->
                    search = StateUI.Error(error)
                }
                .map {
                    searchUIMapper.map(it)
                }.collect {
                    search = if (it.results.isEmpty()) {
                        StateUI.Error(EmptySearchException())
                    } else {
                        StateUI.Success(it)
                    }
                }
        }
    }

}

Test

@ExperimentalCoroutinesApi
@ExperimentalTime
class SearchViewModelTest {

    private lateinit var searchViewModel: SearchViewModel

    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    @get:Rule
    var coroutineRule = TestCoroutineRule()

    @MockK(relaxed = true)
    private lateinit var searchItemUseCase: SearchItemUseCase

    private val searchUIMapper by lazy {
        SearchUIMapper(ItemUIMapper())
    }

    @Before
    fun setup() {
        MockKAnnotations.init(this)
        searchViewModel = SearchViewModel(
            searchItemUseCase,
            searchUIMapper
        )
    }

    @Test
    fun success() = coroutineRule.runBlockingTest {

        val search = getSearchEntity(itemEntityList)
        //Given
        coEvery { searchItemUseCase.execute("") } returns flow {
            emit(search)
        }

        searchViewModel.searchItem("")

        assertEquals(StateUI.Success(searchUIMapper.map(search)), searchViewModel.search)
    }

    @Test
    fun emptySearch() = coroutineRule.runBlockingTest {
        val search = getSearchEntity(emptyList())
        //Given
        coEvery { searchItemUseCase.execute("") } returns flow {
            emit(search)
        }

        //When
        searchViewModel.searchItem("")

        //Verify
        assertTrue((searchViewModel.search as StateUI.Error<SearchUI>).data is EmptySearchException)
    }

    @Test
    fun error() = coroutineRule.runBlockingTest {

        val error = NoConnectivityException()
        //Given
        coEvery { searchItemUseCase.execute("") } returns flow {
            throw error
        }

        //When
        searchViewModel.searchItem("")

        assertEquals(StateUI.Error<SearchUI>(error), searchViewModel.search)
    }

}
Emmanuel Montt
  • 346
  • 1
  • 6