How to Unit Test live Data?

Let's Get The Job Done!

How to Unit Test live Data?

In this article we are going to discuss how we could unit test the Live Data object from googles architectural components.

If you have tried to test live Data Object on Android platform you have certainly encountered the error below.

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:115)
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)
at pl.pbochenski.archcomponentstest.MainViewModelTest.shouldGetPostsAndHaveACopyOfIt(MainViewModelTest.kt:48) ...

That’s because the Live Data PostValue method is run on the Main Looper thread and the main thread nor any android dependency is available for Unit testing, so how to handle this kind of challenge?

To overcome such a misfortune you have to simply add below dependency to the Gradle:

testImplementation 'android.arch.core:core-testing:1.1.1'

then in the test class add the below code as a class field:

// Java : 
 @Rule
 public InstantTaskExecutorRule instantRule = new InstantTaskExecutorRule() ;


// kotlin :
 @Rule
 @JvmField
 val rule = InstantTaskExecutorRule()

That’s it, Here you can test LiveData objects without any headache!.

    
@Test
public void givenDataSource_whenFetchingReuslt_thenTrue(){

    Observer<List<Items>> corridorObserver = new Observer()

    dataSource.getItems().observeForever( corridorObserver);

    dataSource.nextPageCorridor(1);

    verify(service).getItems() ;

}

Also there is another bonus trick that you can use to get your power back. you can define a custom observer for the LiveData and cache the LiveData Value on the OnChange Method:

public class TestLiveDataObserver<T> implements Observer<T> {


    private List<T> items = new ArrayList<>() ;

    @Override
    public void onChanged(T t) {

        corridors.add(t) ;

    }


    public List<T> getItems() {
        return corridors;
    }

    public void setItems(List<T> corridors) {
        this.corridors = corridors;
    }
}

Then in the code you can access LiveData Cached value easily like this :

@Test
public void givenDatasource_whenFetchingReuslt_thenTrue(){

    TestLiveDataObserver<List<Item>> corridorObserver = new TestLiveDataObserver()

    dataSource.getItems().observeForever(itemObserver);

    dataSource.getItems(); 

    assertEquals(itemObserver.getItems()  , Collections.emptyList()); ;

}

Hope you enjoy this article.

 

Leave a Reply

Your email address will not be published. Required fields are marked *