The Startup
Published in

The Startup

Exercises in futility: Unit-testing LiveData, ViewModels and Coroutines

This is part of a series head-scratching my way into coroutines. It can be read as a standalone although you might be missing out on some spicy memes here and here.

Testing ViewModels without losing the will to live

A ViewModel “sits” quite close to the activity/fragment. Something that a user would be looking at generally, even if they are unaware.

You would think that a professional keyboard user walking into your ViewModel test file would probably be able to read the test methods and make some sense of what’s going on at the screen level without even running your app, right? 🤡

Get some dependencies first

Where we left off

Our little ViewModel looks like this:

Most android apps out there are based on this simple premise.

The PostViewModel is responsible for fetching a post from Reddit while the calling activity/fragment is responsible for observing the stateData variable.

Googling “LiveData testing how to” (and its myriad of variations), you’ll find all sorts of smart extension functions (LiveDataTestUtil and others like it) that hide what’s going on and are not really that useful on a number of occasions.

A simple solution is to use a LifeCycleTestOwner helper class. (at the cost of adding a few extra lines of code that is)

We’ll use this to replicate the presence of an activity or fragment in our test class.

The setup

  • Using the CoroutineTestRule we have full control of running everything on the TestCoroutineDispatcher. You can find more on this rule here.
  • InstantTaskExecutorRule comes bundled in the androidx.arch.core:core-testing library and should be used when testing LiveData.
  • The stateObserver variable is just a mock. Think of it as the observer in the activity/fragment.
  • The lifeCycleTestOwner plays the role of the lifecycle of the activity/fragment and is created and destroyed before each test.


Unit tests do have their place, although they can get a bit overboard. A rather sad test on this occasion really goes for isolation and tests every little thing that can happen separately.

While this test will pass and it does verify a certain behavior, we can do better and provide some sort of documentation and high level view of the ViewModel to a stranger who doesn’t really know what going on in that file.

Wew lad

Unit tests will never replace decent UI tests on android (or your userbase throwing 1-star reviews on your app because it’s crashing all over the place), but this is good enough to build on for more complex screens. Much of the verbosity can also be decreased by using extension functions and test rules.





Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +756K followers.

Recommended from Medium

Android App as AWS IoT Thing

Retrofit 2.0 — A new way to work with Retrofit 2.0 in Android — Android Architecture

Flutter app development made easy. Learn the basics — LetgOShots

Getting ready for Android 12 —Using new Lint checks for writing compliant code

Android: Sticky view at the bottom of bottom sheet dialog fragment

A Deep Dive Into Internationalizing Jetpack Compose Android Apps

Perfectus: Setup Firebase for Sign-in

It’s Show Time App using Huawei Location & Site Kit

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
Costa Fotiadis

Costa Fotiadis

Android dude @JustEatUK

More from Medium

Try Saving LiveData Coroutine State

Callback function to suspend function and Flow (Part 1)

Android Unit Testing With MockWebServer and Truth Assertion Library

Integrate Version catalog in Android