Kotlin Coroutines MVVM Retrofit UnitTestCases — Part3

This story explains about Kotlin Coroutines with MVVM Architecture and Retrofit with Sample examples.

App Flow :

The Coroutine sample that will be explained in the story contains 3 screens

(1) Login Screen

(2) List Screen

(3) List Detail Screen

(4)Corresponding Unit test cases with Mockito.

Used Libraries:

The below libraries are used as part of this implementation

Mockito : For unit testcases

Retrofit : For Making API calls

CoRoutines : Used in combination with Retrofit to make API calls in the separate thread.

Dagger : Dagger2 is used for Dependency Injection

MVVM : MVVM Architecture is followed to build the screens.

The below URL is used to make API calls in the above screens:

Detailed Explanation of Each of the screens:

(1) Login Screen : Contains user interface that display 2 fields Email and password which are pre-populated for the purpose of the tutorial.

When login button is clicked , post API call is performed to validate the entered credentials.

Login Screen

NetworkAPIService: The below interface contains list of suspend functions to make API calls .

@Post : For Login to validate login validate credentials by posting to Server

@GET : fun fetchUsers() Will fetch list of all users from API server

@GET: fun fetchSelectedUsers() : Will fetch information about selected user in List to display user details .

interface NetworkAPIService {

suspend fun validateLogin(@Body loginModel: LoginModel) : Response<TokenModel>

suspend fun fetchUsers(@Query("page") page :Int): Response<RetroResult>

suspend fun fetchSelectedUsers(@Path("id") id : Int): Response<RetroResultUser>

NetworkURL: This is the companion object class that contains information about the URL.

class NetworkURL {
companion object {
const val NETWORK_BASE_URL = "https://reqres.in"
const val REQUEST_TIMEOUT = 60L

ViewModels : These are the classes where business logic to handle API calls .

LoginViewModelFactory: This class injects Retrofit instance and it initialized corresponding view model with a Dispatcher.Main and networkAPIService as arguments .

Note: Dispatcher.Main to be passed to ViewModel , in order to unit test the view model.

class LoginViewModelFactory : ViewModelProvider.Factory {
lateinit var retrofit: Retrofit
lateinit var networkAPIService: NetworkAPIService
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
networkAPIService = retrofit.create(NetworkAPIService::class.java)
if (modelClass.isAssignableFrom(LoginViewModel::class.java)) {
return LoginViewModel(Dispatchers.Main,networkAPIService) as T
throw IllegalArgumentException("Unknown ViewModel class")

ViewModel: (LoginViewModel)

This file contains all the logic related to posting login credential data to the API service for validation. This class uses Coroutines to make API calls .

View Model takes Dispatcher and NetworkService API as arguments:

class LoginViewModel(
private val dispatcher: CoroutineDispatcher,
private val apiService: NetworkAPIService
) : ViewModel(), LifecycleObserver

Sample Code for the function that makes API call:

fun validateLogin(loginModel: LoginModel){

viewModelScope.launch(dispatcher) {
val response = apiService.validateLogin(loginModel)
if(response.isSuccessful) {

// println("Response Error body during failure is ${JSONObject(response.errorBody()?.string()).get("error")} ")
val errorMessage = JSONObject(response.errorBody()?.string()).get("error").toString()
println("Response Error Message $errorMessage")

}catch (e : Exception){
errorOnAPI.postValue("Something went wrong::${e.localizedMessage}")

UserList Screen:

This screen contains a Recycler View to fetch data from the API.

User List Screen

The above screen uses @Get service call to fetch data from the API.

UserDetail Screen : Launched when clicked on any of the list item.

User Detail Screen

GitHub Link for the code related to above screens:



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store