Created
November 22, 2019 18:04
-
-
Save AdamMc331/1362feb28241ebfac320c21f6e24f341 to your computer and use it in GitHub Desktop.
The files used in a blog post about unit testing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed class PokemonListState { | |
object Loading : PokemonListState() | |
object Empty : PokemonListState() | |
class Loaded(val data: List<Pokemon>) : PokemonListState() | |
class Error(val error: Throwable?) : PokemonListState() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface PokemonRepository { | |
fun getPokemon(): List<Pokemon> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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