George Venios
Jul 19, 2017 · 2 min read

Building Done, I used Android Architecture Components, Data Binding and Room. Inevitably, while writing tests I found myself needing to assert on code that’s called inside a LiveData observer, in its onChanged() callback.

While easy, the fix wasn’t obvious, and even after Googling, the answer wasn’t readily available so I’m posting it here to help future users of LiveData.

The problem

Seeing how LiveData itself doesn’t provide a setValue() method, the first step is to create a MutableLiveData object in your tests, pass it to your mock/fake LiveData provider (for example, if you’re using Room this is your mock Dao), and then continue happily asserting on calls made in onChanged().

Try that though and you’re greeted with this crash:

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.at android.os.Looper.getMainLooper(Looper.java)
at android.arch.core.executor.DefaultTaskExecutor.isMainThread(DefaultTaskExecutor.java:58)
at android.arch.core.executor.AppToolkitTaskExecutor.isMainThread(AppToolkitTaskExecutor.java:87)
at android.arch.lifecycle.LiveData.assertMainThread(LiveData.java:408)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:290)
at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)

Which is descriptive enough but all it really says is that you are doomed if you’re trying to setValue() while running plain Java unit tests.

The solution

No need to fret as it turns out you can still use this method to test your LiveData observers!

  • First, add this dependency in your module’s build.gradle file:
testImplementation 'android.arch.core:core-testing:1.0.0-alpha3'

Make sure you use the same version as the rest of your android.arch.* dependencies!

  • Then, in the test class where you need to call setValue() and assert, add this field:
@Rulepublic TestRule rule = new InstantTaskExecutorRule();

Behind the scenes, this bypasses the main thread check, and immediately runs any tasks on your test thread, allowing for immediate and predictable calls and therefore assertions.


I hope this helps more folks avoid getting stuck on this as it has been a major annoyance during my experiments with the otherwise straightforward Android Components library.

Download Done to see the resulting app!

pxHouse

Official blog

George Venios

Written by

Android Engineer @ Shazam, One Man Band @ pxHouse.

pxHouse

pxHouse

Official blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade