#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.