Skip to content

Instantly share code, notes, and snippets.

@GabriellCosta
Last active October 25, 2018 03:47
Show Gist options
  • Save GabriellCosta/e6bc18cf653192ab88e08584f849d117 to your computer and use it in GitHub Desktop.
Save GabriellCosta/e6bc18cf653192ab88e08584f849d117 to your computer and use it in GitHub Desktop.
Nesse modo temos nosso Robot contendo toda a lógica do que é feito alem de ter todas as dependências de teste
package com.gabrielcosta.weather.feature.forecast
import android.arch.lifecycle.MutableLiveData
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import com.gabrielcosta.weather.R
import com.gabrielcosta.weather.Robot
import com.gabrielcosta.weather.feature.forecast.entity.ForecastItemVO
import com.gabrielcosta.weather.feature.forecast.entity.ForecastVO
import com.gabrielcosta.weather.util.RecyclerViewItemCountAssertion.Companion.withItemCount
import com.gabrielcosta.weather.util.applyAsMock
import com.gabrielcosta.weather.util.call
import com.gabrielcosta.weather.util.prepareAppSettings
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import org.hamcrest.CoreMatchers.not
class ForecastFragmentRobots : Robot {
private val viewModel: ForecastViewModelRecipe = mock()
private val emptyState = MutableLiveData<Nothing>()
private val forecastLiveData = MutableLiveData<ForecastVO>()
override fun setup() {
viewModel.applyAsMock()
whenever(viewModel.fetchForecast(any(), any())).then { forecastLiveData }
whenever(viewModel.getEmptyStateObserver()).thenReturn(emptyState)
prepareAppSettings()
}
fun numberOfForecastItems(numberOfItems: Int) {
onView(withId(R.id.rv_forecast)).check(withItemCount(numberOfItems))
}
fun postItems() {
forecastLiveData.postValue(createForecastVO())
}
fun setEmptyForecastList() {
emptyState.call()
}
fun noListDisplayed() {
onView(withId(R.id.rv_forecast))
.check(matches(not(isDisplayed())))
}
fun errorText() {
onView(withId(R.id.error_state_description))
.check(matches(withText("Don\'t have any weather now : (")))
}
fun retry() {
onView(withId(R.id.error_state_retry_button)).perform(ViewActions.click())
verify(viewModel, times(2)).fetchForecast(any(), any())
}
private fun createForecastVO(): ForecastVO {
return ForecastVO(listOf(
ForecastItemVO("Clear Sky on Thursday", "280 K", "01d"),
ForecastItemVO("Clear Sky on Thursday", "280 K", "01d"),
ForecastItemVO("Clear Sky on Monday", "293 K", "01d"),
ForecastItemVO("Clear Sky on Monday", "270 K", "01d"),
ForecastItemVO("Scatter clouds on Friday", "220 K", "01d")))
}
}
package com.gabrielcosta.weather.feature.forecast
import android.support.test.runner.AndroidJUnit4
import com.gabrielcosta.weather.FragmentTestRule
import com.gabrielcosta.weather.RobotRule
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ForecastFragmentTest {
@get:Rule
val rule = FragmentTestRule<ForecastFragment>()
@get:Rule
val forecast = RobotRule(ForecastFragmentRobots())
@Before
fun setup() {
forecast.setup()
rule.launchFragment(ForecastFragment())
}
@Test
fun shouldHaveFiveItems() {
forecast {
postItems()
numberOfForecastItems(5)
}
}
@Test
fun whenEmptyList_ShouldHaveEmptyState() {
forecast {
setEmptyForecastList()
noListDisplayed()
errorText()
}
}
@Test
fun whenRetryClicked_ShouldCallViewModelAgain() {
forecast {
setEmptyForecastList()
retry()
}
}
}
package com.gabrielcosta.weather
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
fun <T> createRobots(func :T.() -> Unit, robot: T) = robot.apply { func() }
interface Robot {
fun setup()
}
class RobotRule<T : Robot>(private val robot: T) : TestRule {
override fun apply(base: Statement, description: Description?): Statement {
return object : Statement() {
override fun evaluate() {
base.evaluate()
}
}
}
fun setup() = robot.setup()
operator fun invoke(func: T.() -> Unit) = createRobots(func, robot)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment