Skip to content

Instantly share code, notes, and snippets.

@pamartineza
Created May 15, 2019 14:41
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 pamartineza/e0993964c2776eec682e80cc8aa38551 to your computer and use it in GitHub Desktop.
Save pamartineza/e0993964c2776eec682e80cc8aa38551 to your computer and use it in GitHub Desktop.
Coroutines and Testing
////////////
// Kotlin //
////////////
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1"
////////////////
// Unit Tests //
////////////////
testImplementation "junit:junit:4.12"
testImplementation "org.mockito:mockito-core:2.27.0"
testImplementation "org.mockito:mockito-inline:2.27.0"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.1"
sealed class Data {
class Success(content: String) : Data()
class Failure() : Data()
}
class Repository() {
suspend fun fetchRemoteData() : Data {
return try {
//pseudocode that takes time to execute, in this case a Firebase Task
val content = Firebase.get("whatever").await
Success(content)
} catch (exception: FirebaseException) {
Failure()
}
}
}
class MyPresenter(val view: IMyView, val repository: Repository): CoroutineScope {
val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
fun doStuff() {
launch {
view.showProgress()
val data = repository.fetchRemoteData()
view.populateScreen(data)
view.hideProgress()
}
}
fun onViewDestroy() {
job.cancel()
}
interface IMyView {
fun showProgress()
fun populateScreen(data: Data)
fun hideProgress()
}
}
class MyPresenterTest() {
val mockView: IMyView = mock()
val mockRepo: Repo = mock()
val mockData: Data = mock()
val testCoroutineContext = TestCoroutineDispatcher()
lateinit var presenter: MyPresenter
@Before
fun setUp() {
Dispatchers.setMain(testCoroutineContext as CoroutineDispatcher)
presenter = MyPresenter(mockView, mockRepo)
}
@After
fun tearDown() {
presenter.onViewDestroy()
Dispatchers.resetMain()
}
@Test
fun testDoStuff() = testCoroutineContext.runBlockingTest {
//given
whenever(mockRepo.fetchRemoteData()).thenReturn(mockData)
//when
presenter.doStuff()
//then
verify(mockView).showProgress()
verify(mockRepo).fetchRemoteData()
verify(mockView).populateScreen(mockData)
verify(mockView).hideProgress()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment