Skip to content

Instantly share code, notes, and snippets.

@AdamMc331
Created November 22, 2019 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AdamMc331/1362feb28241ebfac320c21f6e24f341 to your computer and use it in GitHub Desktop.
Save AdamMc331/1362feb28241ebfac320c21f6e24f341 to your computer and use it in GitHub Desktop.
The files used in a blog post about unit testing.
sealed class PokemonListState {
object Loading : PokemonListState()
object Empty : PokemonListState()
class Loaded(val data: List<Pokemon>) : PokemonListState()
class Error(val error: Throwable?) : PokemonListState()
}
class PokemonListViewModel(
private val repository: PokemonRepository
) {
private var state: PokemonListState? = null
val pokemon: List<Pokemon>?
get() = (state as? PokemonListState.Loaded)?.data
val showLoading: Boolean
get() = state is PokemonListState.Loading
val showError: Boolean
get() = state is PokemonListState.Error
val showData: Boolean
get() = state is PokemonListState.Loaded
val showEmptyState: Boolean
get() = state is PokemonListState.Empty
init {
fetchPokemonList()
}
private fun fetchPokemonList() {
state = PokemonListState.Loading
try {
val pokemonList = repository.getPokemon()
state = if (pokemonList.isEmpty()) {
PokemonListState.Empty
} else {
PokemonListState.Loaded(pokemonList)
}
} catch (error: Throwable) {
state = PokemonListState.Error(error)
}
}
}
class PokemonListViewModelRobot {
private lateinit var viewModel: PokemonListViewModel
fun buildViewModel(repository: PokemonRepository): PokemonListViewModelRobot {
this.viewModel = PokemonListViewModel(repository)
return this
}
fun assertPokemonList(expectedPokemon: List<Pokemon>?): PokemonListViewModelRobot {
val actualPokemon = viewModel.pokemon
assertEquals(expectedPokemon, actualPokemon)
return this
}
fun assertShowLoading(expectedShowing: Boolean): PokemonListViewModelRobot {
val actualShowing = viewModel.showLoading
assertEquals(expectedShowing, actualShowing)
return this
}
fun assertShowData(expectedShowing: Boolean): PokemonListViewModelRobot {
val actualShowing = viewModel.showData
assertEquals(expectedShowing, actualShowing)
return this
}
fun assertShowError(expectedShowing: Boolean): PokemonListViewModelRobot {
val actualShowing = viewModel.showError
assertEquals(expectedShowing, actualShowing)
return this
}
fun assertShowEmptyState(expectedShowing: Boolean): PokemonListViewModelRobot {
val actualShowing = viewModel.showEmptyState
assertEquals(expectedShowing, actualShowing)
return this
}
}
class PokemonListViewModelTest {
private lateinit var testRobot: PokemonListViewModelRobot
@Before
fun setUp() {
testRobot = PokemonListViewModelRobot()
}
@Test
fun successfulFetch() {
val expectedPokemon = listOf(Pokemon(name = "Squirtle"))
testRobot
.buildViewModel(repository = SuccessfulRepository())
.assertPokemonList(expectedPokemon)
.assertShowData(true)
.assertShowError(false)
.assertShowLoading(false)
.assertShowEmptyState(false)
}
@Test
fun emptyFetch() {
testRobot
.buildViewModel(repository = EmptyRepository())
.assertPokemonList(null)
.assertShowEmptyState(true)
.assertShowError(false)
.assertShowLoading(false)
.assertShowData(false)
}
@Test
fun errorFetch() {
testRobot
.buildViewModel(repository = ErrorRepository())
.assertPokemonList(null)
.assertShowError(true)
.assertShowLoading(false)
.assertShowData(false)
.assertShowEmptyState(false)
}
}
interface PokemonRepository {
fun getPokemon(): List<Pokemon>
}
class SuccessfulRepository : PokemonRepository {
override fun getPokemon(): List<Pokemon> {
return listOf(Pokemon(name = "Squirtle"))
}
}
class EmptyRepository : PokemonRepository {
override fun getPokemon(): List<Pokemon> {
return emptyList()
}
}
class ErrorRepository : PokemonRepository {
override fun getPokemon(): List<Pokemon> {
throw Throwable("Whoops")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment