#6 One thing to look out for when using LiveData and Transformations

#6 One thing to look out for when using LiveData and Transformations

If you were to unit test LiveData and LiveData transformations you might write a test like this:

class MainViewModel(initialArticle: Article) : ViewModel() {

    private val _articleLiveData = MutableLiveData<Article>()
    val articleLiveData: LiveData<Article> = _articleLiveData
    val articleTitleLiveData: LiveData<String> = Transformations.map(_articleLiveData) { it.title }

    init {
        _articleLiveData.value = initialArticle
    }
}

class MainViewModelTest {

    @get:Rule
    var rule: TestRule = InstantTaskExecutorRule()

    private lateinit var viewModel: MainViewModel

    private val initialArticle =
        Article("first Article", "text of first article. blablalbalb. blalbla. bla.")

    @Before
    fun setup() {
        viewModel = MainViewModel(initialArticle)
    }

    @Test
    fun testArticleEmission() {
        Assert.assertEquals(initialArticle, viewModel.articleLiveData.value)
    }

    @Test
    fun testArticleTitleEmission() {
        Assert.assertEquals(initialArticle.title, viewModel.articleTitleLiveData.value)
    }
}

But it might surprise you that the 2nd test testArticleTitleEmission will fail. Why is that?

Turns out that transformed LiveData does not emit values without an observer. So to make the test pass you need to adjust it in the following way:

@Test
fun testArticleTitleEmission() {
    viewModel.articleTitleLiveData.observeForever { } // This is the important bit!!
    Assert.assertEquals(initialArticle.title, viewModel.articleTitleLiveData.value)
}

Note: It doesn’t matter what your observer does, just that it exists.

Now both tests will pass.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert