Search⌘ K

Testing Android Functions That Launch Coroutines

Explore how to test Android components that launch Kotlin coroutines by replacing the Main dispatcher with a test dispatcher. Understand the use of StandardTestDispatcher, control coroutine timing with advanceTimeBy and advanceUntilIdle, and implement JUnit rules or extensions to manage test lifecycle and dispatcher setup. This lesson empowers you to write efficient and reliable tests for coroutine-based Android code.

We typically start coroutines on ViewModels, Presenters, Fragments, or Activities on Android. These are fundamental classes, and we should test them. Think of the MainViewModel implementation below.

Kotlin 1.5
class MainViewModel(
private val userRepo: UserRepository,
private val newsRepo: NewsRepository,
) : BaseViewModel() {
private val _userName: MutableLiveData<String> =
MutableLiveData()
val userName: LiveData<String> = _userName
private val _news: MutableLiveData<List<News>> =
MutableLiveData()
val news: LiveData<List<News>> = _news
private val _progressVisible: MutableLiveData<Boolean> =
MutableLiveData()
val progressVisible: LiveData<Boolean> =
_progressVisible
fun onCreate() {
viewModelScope.launch {
val user = userRepo.getUser()
_userName.value = user.name
}
viewModelScope.launch {
_progressVisible.value = true
val news = newsRepo.getNews()
.sortedByDescending { it.date }
_news.value = news
_progressVisible.value = false
}
}
}

Instead of viewModelScope, there might be our own scope, and instead of ViewModel, it might be Presenter, Activity, or some other class. It does not matter for our example. As in every class that starts coroutines, we should use StandardTestDispatcher as a part of the scope. Previously, we needed to inject a different scope with a dependency ...