# Kotlin Everywhere. Coroutines, Tests, Robots and much more…

The year is 2019 and with every passing month, technology and the stack underneath are upgrading. For eg: The Android permissions which were open for all, became dangerous, then restricted, and then permissible only when required. Things are changing fast for the better and more solid Android development with core principles getting intact.

> Change is the only constant — Mahatma Gandhi

Two years back when [TvFlix repository](https://github.com/reactivedroid/TvFlix) was created, the aim was to follow the latest tech stack and architecture. So the app was first designed in MVP pattern and then last year [migrated to MVVM by Android Architecture Components powered by RxJava and Dagger 2](https://medium.com/mindorks/migration-from-mvp-to-mvvm-using-android-architecture-components-4bc058a1f73c). Now, the complete TvMaze repository has been rewritten in Kotlin with the latest tech stack and language goodness. So let’s dive in.

### Upgrade to Moshi

TvMaze earlier relied upon [Gson](https://github.com/google/gson) for converting JSON to POJO and back. To promote immutability, [AutoValue](https://github.com/google/auto/) was being used with [Parcelable](https://github.com/rharter/auto-value-parcel) and [Gson](https://github.com/rharter/auto-value-gson) extensions by [Ryan Harter](https://medium.com/u/eeff4b2fb500). Gson TypeAdapters helped in avoiding reflection while making the conversion. AutoValue also helped in creating builders while still maintaining immutability. A typical AutoValue class will look like this:

Too much of a boilerplate isn’t it?! Also, since the libraries are moving to Kotlin first then why not upgrade for a better future with the goodness of the language? [Moshi](https://github.com/square/moshi) solves all of the above to stand out as a better JSON serialization library. It provides first-hand Kotlin support with `moshi-kotlin` and [`codegen`](https://medium.com/@ZacSweers/exploring-moshis-kotlin-code-gen-dec09d72de5e). Kotlin data classes are immutable and `copy` the method helps in creating the builder. Kotlin's `@Parcelize` helps to replace the AutoValue parcel extension thus removing the complete AutoValue library. So the above data class becomes pretty neat and small.

```kotlin
@Parcelize
@JsonClass(generateAdapter = true)
data class Episode(
val id: Long,
val url: String?) : Parcelable
```

### Migration to Coroutine from RxJava — A Paradigm Shift

[Coroutines](https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html) are new ways to encourage asynchronous programming. They help in synchronously writing asynchronous operations. There are tons of articles that already explain the Whys and Hows of Coroutines. So let’s jump directly into implementation.

With [Retrofit](https://github.com/square/retrofit) latest release, Coroutine is officially supported. That means you can remove retrofit’s `RxJava2CallAdapterFactory` . Just make all the retrofit calls to `suspend` functions and return the values directly.

```kotlin
interface TvMazeApi {
    @GET("/schedule")
    suspend fun getCurrentSchedule(
        @Query("country") country: String,
        @Query("date") date: String
    ): List<Episode>

    @GET("/shows")
    suspend fun getShows(@Query("page") pageNumber: Int): List<Show>
}
```

The home screen of TvMaze shows the list of shows fetched from the TVDB API clubbing them with the user’s favorites. A user can mark any show as a favorite which gets stored via [Room](https://developer.android.com/topic/libraries/architecture/room). Room library now comes with Coroutine support which means all the Dao operations can be suspended thus removing RxJava completely.

Now we are ready to load data for Home screen. `HomeViewModel` previously relied on RxJava heavily. When the `onScreenCreated` was called, two streams: one from API and the other from DB were zipped using `Single.zip`to give the combined result.

```java
public void onScreenCreated() {
    isLoading.setValue(true);  
    String currentDate = getCurrentDate();   
   
    Single<List<Show>> favoriteShows = favoriteShowsRepository
    .getAllFavoriteShows()
    .map(this::convertToShows);       
 
    Single<List<Episode>> episodes = tvMazeApi.getCurrentSchedule(COUNTRY_US, currentDate);
    Single<List<Episode>> zippedSingleSource = 
    Single.zip(episodes, favoriteShows, this::favorites);
Disposable homeDisposable = zippedSingleSource.observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(this::onSuccess, this::onError);
    compositeDisposable.add(homeDisposable);   
}
```

Let's convert the above function to coroutines. Since Retrofit and Room are already on Coroutine support, they respect the `suspend` calls. That means, `viewModelScope` will launch a new coroutine, which then calls retrofit’s suspend function `tvMazeApi.getCurrentSchedule`. The retrofit will move the network operation to the IO-bound coroutine via `Dispatchers.IO` and once the suspending function is complete, it will return the result on `Dispatchers.Main`. A similar case will happen with Room `suspend` calls.

```kotlin
fun onScreenCreated() {
    homeViewStateLiveData.value = Loading
    val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
        onError(exception)
    }
    // viewModelScope launches the new coroutine on Main Dispatcher internally
    viewModelScope.launch(coroutineExceptionHandler) {
        // Get favorite shows from db, suspend function in room will launch a new coroutine with IO dispatcher
        val favoriteShowIds = favoriteShowsRepository.allFavoriteShowIds()
        // Get shows from network, suspend function in retrofit will launch a new coroutine with IO dispatcher
        val episodes = tvMazeApi.getCurrentSchedule(COUNTRY_US, currentDate)

        // Return the result on main thread via Dispatchers.Main
        homeViewStateLiveData.value = Success(HomeViewData(getShowsWithFavorites(episodes, favoriteShowIds)))
    }
}
```

`viewModelScope` is a lifecycle Kotlin extension to support coroutines. This handles the cancellation of the coroutine when ViewModel `onCleared` is called so that you don’t have to worry about holding the `Job` instance and explicitly canceling it. `CoroutineExceptionHandler` handles the exceptions being thrown at any Coroutine so that the errors can be propagated and displayed to the user.

### Unit Testing Coroutine

We have introduced Coroutine to replace RxJava both on the network and DB layer. Time to put them to the test. We will use [Mockito](https://github.com/mockito/mockito) with `mockito-kotlin` for better mocking APIs. The test will run on `RobolectricTestRunner` to incorporate Android resources into testing.

#### Testing Room With Coroutine

TvFlix stores the user-marked favorite shows in Db. All the CRUD operations happen via `FavoriteShowsRepository`

%[https://gist.github.com/reactivedroid/0f22f2e0392aed60640c6151ebff1450] 

To test `FavoriteShowsRepository`, we will create an in-memory database via `Room.inMemoryDatabaseBuilder`. The in-memory database provides faster CRUD operations on the database and also ensures that the database disappears when the process is killed. To effectively test coroutines, we will rely on [Coroutine test library](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/)(still in development). Let’s check the `FavoriteShowsRepositoryTest` class and understand the flow:

%[https://gist.github.com/reactivedroid/9451a743bdfd767b6159600811130408] 

We mock the context and provide it to Room to create the database. Mocking of context is possible by `mockito-inline` which helps in mocking final classes. With the database, we get the mock `showDao` and create our repository. `runBlocking` runs the new coroutine on the current thread until its completion. We launch the new Coroutine or run the suspending function in this block. We have used [`Truth`](https://github.com/google/truth) library which provides better and more expressive assertions.

#### Testing ViewModel

`InstantTaskExecutorRule` is an Android architecture testing component that executes the task in the same thread. `MainCoroutineRule` sets the main Coroutines Dispatcher to `TestCoroutineScope` for better control over coroutine execution in unit testing. `HomeViewModel` is dependent upon `TvMazeApi` and `FavoriteShowsRepository`. So, we mock the required dependencies and then use `@InjectMocks` to mock `HomeViewModel`. To test, if the home screen is loaded with shows and without favorites, we first stub network and DB calls. Then, we verify whether the loader is shown or not. `pauseDispatcher` pauses the execution of a coroutine to verify the initial `Loading` state. After verification, we `resumeDispatcher` to proceed with execution of pending coroutine actions.

%[https://gist.github.com/reactivedroid/a5d4317486193a8a7e4eac74d3aece20] 

Initially, when `HomeViewModelTest` was run, it failed because of the way the tests were written. Read more [here](https://stackoverflow.com/questions/57239510/coroutine-unit-testing-fails-for-the-class). Then after further readings and listening to an awesome [Podcast](http://androidbackstage.blogspot.com/2019/07/episode-117-kotlin-coroutines.html), it was found that we don’t explicitly have to worry about context-switching with Retrofit and Room. The libraries that come with Coroutine support, own the `suspend` functions and move them off the UI thread on their own. Thus, they reduce the hassles of handling thread callbacks by the developers in a big way. The result is pretty neat asynchronous calls written synchronously with no callbacks and better readability.

### UI Testing — Robot Pattern

[Robot Pattern](https://academy.realm.io/posts/kau-jake-wharton-testing-robots/) was introduced by [Jake Wharton](https://medium.com/u/8ddd94878165) to provide a better separation of concern for UI testing. The pattern aims at properly managing the UI test by separating the What and How of it. Meaning that what is to be tested should not concern *How* it is to be tested. Both should have clear separation so that maintenance of UI tests becomes easy.

Say, we want to test the Home Screen, whether it shows the list of *Popular Shows,* and whether *Add to Favorites* is working fine or not. This is the *What* of Robot Pattern. The *How* of this will be taken care of by `HomeRobot` which handles all the verification/assertions/actions via `Espresso`.

%[https://gist.github.com/reactivedroid/ed947609a06ee6e550dfffce0decc560] 

`LoadingIdlingResource` tells Espresso to wait until the list of`shows` is fetched and displayed on the screen. This is achieved via the visibility of the progress bar. As an alternative, some suggest using [Espresso in production code](https://medium.com/androiddevelopers/android-testing-with-espressos-idling-resources-and-testing-fidelity-8b8647ed57f4), but having a test code in production does not look good(Debatable). The final piece is our Kotlin Robot `HomeRobot`

%[https://gist.github.com/reactivedroid/f5aa71341c982213b02798f33f5e13d8] 

This Robot is loaded with Kotlin goodness to remove the builder pattern and use language advanced primitives. Know more [here](https://academy.realm.io/posts/kau-jake-wharton-testing-robots/).

### Future is Bright

RxJava is a powerful library for asynchronous programming packed with tons of operators to get along. Coroutines are still new, and the Android community is slowly accepting them. Heavy development around [Flow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/) and [Channels](https://kotlinlang.org/docs/reference/coroutines/channels.html), are bridging this gap. Kotlin surely bags a punch with superb language features. With an awesome community, the road to the future of Android Application development looks even brighter. So why wait, go ahead and give a boost to your Android development with Kotlin now. 🚀

%[https://github.com/reactivedroid/TvFlix]
