I am developing a toy Android app using Kotlin (Coroutine).
I am familiar with Rx more than Coroutine.
I feel that Coroutine difficult more than Rx.
Anyway here is my Presenter code:
class NowPlayingPresenter(
private val view: NowPlayingContract.View,
private val getMovies: GetNowPlayingMovies,
private val uiContext: CoroutineContext = Dispatchers.Main,
ioContext: CoroutineContext = Dispatchers.IO
) : NowPlayingContract.Presenter, CoroutineScope, AnkoLogger {
override val coroutineContext: CoroutineContext = Job() + ioContext
override fun unsubscribe() {
coroutineContext.cancel()
}
override fun getMoviesNowPlaying() {
view.showProgressBar(View.VISIBLE)
view.hideError()
launch {
try {
val movies = getMovies.get()
// 'movies' is always null!!! I don't know why...
withContext(uiContext) {
view.showProgressBar(View.GONE)
if (movies.isNullOrEmpty()) {
view.onError(R.string.err_movies_not_exists)
} else {
view.onMoviesLoaded(movies)
}
}
} catch (t: Throwable) {
view.showProgressBar(View.GONE)
view.onError(R.string.err_get_movies_failed)
error("[Y.M.] getMoviesNowPlaying - failed: ${t.message}", t)
}
}
}
}
Here is my GetNowPlayingMovies code, it is just interface:
interface GetNowPlayingMovies {
suspend fun get(): List<SimpleMovie>
}
And below is my JUnit test code:
class MyDataPresenterTest {
@Mock
private lateinit var mockView: NowPlayingContract.View
@Mock
private lateinit var getMovies: GetNowPlayingMovies
private lateinit var presenter: NowPlayingPresenter
private lateinit var inOrder: InOrder
private val mockMovie1 = SimpleMovie("posterpath1", false, "2019-03-01", 10, "hello world1", 10f)
private val mockMovie2 = SimpleMovie("posterpath2", true, "2019-03-02", 20, "hello world2", 9f)
private val mockMovie3 = SimpleMovie("posterpath3", false, "2019-03-03", 30, "hello world3", 8f)
private val mockMovie4 = SimpleMovie("posterpath4", false, "2019-03-04", 40, "hello world4", 7f)
private val mockMovie5 = SimpleMovie("posterpath5", false, "2019-03-05", 50, "hello world5", 6f)
private val mockMovies: List<SimpleMovie> = listOf(
mockMovie1,
mockMovie2,
mockMovie3,
mockMovie4,
mockMovie5
)
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
inOrder = Mockito.inOrder(mockView)
presenter = NowPlayingPresenter(mockView, getMovies, Dispatchers.Unconfined, Dispatchers.Unconfined)
}
@Test
fun getMoviesNowPlayingTest() = runBlocking {
`when`(getMovies.get()).thenReturn(mockMovies)
presenter.getMoviesNowPlaying()
inOrder.verify(mockView).showProgressBar(View.VISIBLE)
inOrder.verify(mockView).hideError()
inOrder.verify(mockView).showProgressBar(View.GONE)
inOrder.verify(mockView).onMoviesLoaded(mockMovies)
}
}
Somebody help me, please?
Here is my full code: https://github.com/yoonhok524/Android-Sandbox/tree/master/kotlin-coroutine
I tried to apply 'Clean architecture' in this project, so the code is not easy to read... maybe...
mockDataobject code.