How to easily test a ViewModel with LiveData and Coroutines

Carlos Daniel
ProAndroidDev
Published in
3 min readMay 2, 2019

--

Photo by ShareGrid on Unsplash

I know, there are plenty of articles, videos and tutorials explaining how to test ViewModels, LiveData and Coroutines, but after have worked in different projects using them, I’d like to share a way which I consider easy, flexible and fast. I’m not saying that this is the best way, but it has worked for my projects very well.

The ViewModel

For simplicity, let’s start with a viewModel class in which we have a method to query a database (it can be or not Room) and we use LiveData to let the view know that some data is available to be shown (for example querying an object or a list of objects) and we also use coroutines to save the data to the local database. Something like this:

The ViewModel class above then query an Auction object, and set the result to a LiveData<Auction> object that will be observed for changes and react to them. Also the saveAuction method is a coroutine to update the local database, which does all the job out of the main thread, so it won’t be blocked, and then after is completed returns to it.

Testing The ViewModel — LiveData

Firstly, let’s show how to test the queryAuctionById method. To successfully test it, we need to take into consideration that this method updates the value of a LiveData object that is being observed. In order to test a LiveData we have several options such as either using observe forever or using a fake lifecycle, or implementing a test implementation of lifecycle owner, among others. The easiest option for me is building an observer instance that owns its own life-cycle. After handling the onChange event we will mark the observer life-cycle as destroyed and let the framework do the rest. Ale Diaferia explains it very well here.

If we don’t do this, unfortunately, by the time we are asserting on it, the value of the LiveData instance will not be populated and will make our test fail. This is because LiveData uses a lifecycle-oriented asynchronous mechanism to populate the underlying data and expects an observer to be registered in order to inform about data changes.

A custom Observer which only observes once

After this, and taking advantage of Kotlin Extensions, we create a LiveData one to call this observer and use within the context of our test:

Now, with our own observer and an extension to call it when we need it, then our test would look like this:

In line 35, we call the method in ViewModel class that will set the value to the LiveData. Then we observe to it in line 36. There we call the extension function of observeOnce, to finally do the assertion. So, our test of the LiveData object is done. Easy, isn’t it?

Testing The Coroutine

Secondly, we have to test our ViewModel’s save method, the one in which we use a coroutine. When I started using coroutines, I thought that testing them was gonna be a little though, but an easy and functional way to test a coroutine or a suspend function is using the runBlocking function. That is all, this will block the main thread to run all the work there, so the saving process run and after it we query the value and do the assertion:

And that’s all folks. A fast and easy way to test ViewModels which use LiveData and Coroutines. This will save you a lot of time and let you all to implement your tests quicker.

--

--