본문 바로가기
안드로이드/UnitTest

안드로이드 livedata 테스트

by 김어찐 2022. 12. 11.
728x90

https://github.com/robolectric/robolectric

 

GitHub - robolectric/robolectric: Android Unit Testing Framework

Android Unit Testing Framework. Contribute to robolectric/robolectric development by creating an account on GitHub.

github.com

 

androidx 테스트를 하기위해서는 robolectirc 모듈을 사용한다.

 

 

 

LiveDataTestUtil.kt

https://github.com/android/architecture-components-samples/blob/master/GithubBrowserSample/app/src/test-common/java/com/android/example/github/util/LiveDataTestUtil.kt

 

GitHub - android/architecture-components-samples: Samples for Android Architecture Components.

Samples for Android Architecture Components. . Contribute to android/architecture-components-samples development by creating an account on GitHub.

github.com

import androidx.annotation.VisibleForTesting
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException


@VisibleForTesting(otherwise = VisibleForTesting.NONE)
fun <T> LiveData<T>.getOrAwaitValue(
    time: Long = 2,
    timeUnit: TimeUnit = TimeUnit.SECONDS,
    afterObserve: () -> Unit = {}
): T {
    var data: T? = null
    val latch = CountDownLatch(1)
    val observer = object : Observer<T> {
        override fun onChanged(o: T?) {
            data = o
            latch.countDown()
            this@getOrAwaitValue.removeObserver(this)
        }
    }
    this.observeForever(observer)

    try {
        afterObserve.invoke()

        // Don't wait indefinitely if the LiveData is not set.
        if (!latch.await(time, timeUnit)) {
            throw TimeoutException("LiveData value was never set.")
        }

    } finally {
        this.removeObserver(observer)
    }

    @Suppress("UNCHECKED_CAST")
    return data as T
}

 

 

 

livedata에서 getOrAwaitValue()를 사용하여 테스트(LiveDataUtil.kt)

package com.ej.tmdbclient.presentation.movie

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.ej.tmdbclient.data.erpository.movie.FakeMovieRepository
import com.ej.tmdbclient.data.model.movie.Movie
import com.ej.tmdbclient.domain.usecase.GetMoviesUseCase
import com.ej.tmdbclient.domain.usecase.UpdateMoviesUsecase
import com.google.common.truth.Truth
import getOrAwaitValue

import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class MovieViewModelTest {

    @get : Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    private lateinit var viewModel : MovieViewModel

    @Before
    fun setUp() {
        val fakeMovieRepository = FakeMovieRepository()
        val getMoviesUseCase = GetMoviesUseCase(fakeMovieRepository)
        val updateMoviesUsecase = UpdateMoviesUsecase(fakeMovieRepository)
        viewModel = MovieViewModel(getMoviesUseCase,updateMoviesUsecase)

    }

    @After
    fun tearDown() {
    }

    @Test
    fun getMovies_returnsCurrentList(){
        val movies = mutableListOf<Movie>()
        movies.add(Movie(1,"overview1","path1","data1","title1"))
        movies.add(Movie(2,"overview2","path2","data2","title2"))

        val currentList = viewModel.getMovies().getOrAwaitValue()
        Truth.assertThat(currentList).isEqualTo(movies)
    }
    @Test
    fun updateMovies_returnsCurrentList(){
        val movies = mutableListOf<Movie>()
        movies.add(Movie(3,"overview3","path3","data3","title3"))
        movies.add(Movie(4,"overview4","path4","data4","title4"))

        val updateList = viewModel.updateMovies().getOrAwaitValue()
        Truth.assertThat(updateList).isEqualTo(movies)
    }
}
728x90

'안드로이드 > UnitTest' 카테고리의 다른 글

안드로이드 테스트 Mock Web Server  (0) 2022.12.13
안드로이드 AndroidTest (room dao test)  (0) 2022.12.11
안드로이드 UnitTest Mock  (0) 2022.12.11
안드로이드 UnitTest  (0) 2022.12.11