Skip to content

Instantly share code, notes, and snippets.

@raulh82vlc
Last active December 27, 2021 01:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save raulh82vlc/a25ba9fb28f02b5ab11447e7377a7ec3 to your computer and use it in GitHub Desktop.
Save raulh82vlc/a25ba9fb28f02b5ab11447e7377a7ec3 to your computer and use it in GitHub Desktop.
SearchTweetUseCaseTest test cases for StateFlow resolution - only latest state is captured
/*
* Copyright (C) 2020 Raul Hernandez Lopez
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.raulh82vlc.tweetsearch.search.domain.usecase
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import com.raulh82vlc.tweetsearch.common.exceptions.BadTokenException
import com.raulh82vlc.tweetsearch.common.threading.TaskThreading
import com.raulh82vlc.tweetsearch.search.MainCoroutineRule
import com.raulh82vlc.tweetsearch.search.addTwoTweets
import com.raulh82vlc.tweetsearch.search.data.datasource.db.model.Tweet
import com.raulh82vlc.tweetsearch.search.data.datasource.db.model.TweetsUIState
import com.raulh82vlc.tweetsearch.search.data.repository.TweetsRepository
import junit.framework.Assert.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
@ExperimentalCoroutinesApi
class SearchTweetUseCaseTest {
@get:Rule
val mainCoroutineRule = MainCoroutineRule()
private val tweetsRepository: TweetsRepository = mock()
private val taskThreading: TaskThreading = mock()
private val tweets: List<Tweet> = addTwoTweets()
private lateinit var underTestUseCase: SearchTweetUseCase
@Before
fun before() {
whenever(taskThreading.ui()).thenReturn(mainCoroutineRule.testDispatcher)
underTestUseCase = SearchTweetUseCase(tweetsRepository, taskThreading)
}
@Test
fun `there are Tweet results`() = mainCoroutineRule.testDispatcher.runBlockingTest {
// when there are tweets
whenever(tweetsRepository.searchTweet(anyString(), anyInt(), anyString())).thenReturn(getTweetsFakeData());
// execute search use case and get stateflow
val stateFlow = underTestUseCase.getStateFlow()
underTestUseCase.execute("query")
// initialise list for StateFlow
val addedStateFlowCollection: MutableList<TweetsUIState?> = mutableListOf()
// add values to StateFlow once collected
addStateFlowState(stateFlow, addedStateFlowCollection)
// check values are filled with a TweetsUIState.ListResultsUIState with tweets inside
assertEquals(1, addedStateFlowCollection.size)
assertNotNull(addedStateFlowCollection[0])
val UIState: TweetsUIState = addedStateFlowCollection[0]!!
assertTrue(UIState is TweetsUIState.ListResultsUIState)
val tweetsUIStateWithResults = UIState as TweetsUIState.ListResultsUIState
assertEquals(tweetsUIStateWithResults.tweets, tweets)
}
@Test
fun `there are empty results`() = mainCoroutineRule.testDispatcher.runBlockingTest {
// when there is empty list of tweets
whenever(tweetsRepository.searchTweet(anyString(), anyInt(), anyString())).thenReturn(getEmptyTweetsFakeData());
// execute search use case and get stateflow
val stateFlow = underTestUseCase.getStateFlow()
underTestUseCase.execute("query")
// initialise list for StateFlow
val addedStateFlowCollection: MutableList<TweetsUIState?> = mutableListOf()
// add values to StateFlow once collected
addStateFlowState(stateFlow, addedStateFlowCollection)
// check values are filled with a TweetsUIState.EmptyUIState
assertEquals(1, addedStateFlowCollection.size)
val UIState: TweetsUIState = addedStateFlowCollection[0]!!
assertEquals(UIState, TweetsUIState.EmptyUIState)
}
@Test
fun `there is an exception`() = mainCoroutineRule.testDispatcher.runBlockingTest {
// when there is an exception
whenever(tweetsRepository.searchTweet(anyString(), anyInt(), anyString())).thenReturn(getThrownException())
// execute search use case and get stateflow
val stateFlow = underTestUseCase.getStateFlow()
underTestUseCase.execute("query")
// initialise list for StateFlow
val addedStateFlowCollection: MutableList<TweetsUIState?> = mutableListOf()
// add values to StateFlow once collected
addStateFlowState(stateFlow, addedStateFlowCollection)
// check values are filled with a TweetsUIState.ErrorUIState
assertEquals(1, addedStateFlowCollection.size)
val UIState: TweetsUIState = addedStateFlowCollection[0]!!
assertTrue(UIState is TweetsUIState.ErrorUIState)
val tweetsUIStateWithError = UIState as TweetsUIState.ErrorUIState
assertEquals(tweetsUIStateWithError.msg, "token could not be retrieved")
}
private fun addStateFlowState(stateFlow: StateFlow<TweetsUIState?>, addedStateFlowCollection: MutableList<TweetsUIState?>) {
stateFlow
.onEach {
addedStateFlowCollection.add(it)
}.launchIn(mainCoroutineRule.testScope)
}
private fun getTweetsFakeData(): Flow<List<Tweet>>
= flowOf(tweets, tweets)
private fun getEmptyTweetsFakeData(): Flow<List<Tweet>>
= flow {
emit(emptyList())
}
private fun getThrownException(): Flow<List<Tweet>>
= flow {
throw BadTokenException("token could not be retrieved")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment