Что не так с тестированием LiveData? Тест не проходит - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь протестировать ViewModel с LiveData, но есть некоторые проблемы. Я не могу получить это. Мой тест не проходит только в одном случае - значение последнего элемента HashMap равно true. Но испытания проходят любые другие случаи

Вот мой тест, который не проходит

class PermissionsViewModelTest{
    @get:Rule
    var rule: TestRule = InstantTaskExecutorRule()
    lateinit var viewModel: PermissionsViewModel
    @Before
    fun setUp() {
        viewModel = PermissionsViewModel()
    }

   //Omited

   @Test
   fun `Should post false if permissions is not granted`() {
        val permissions = hashMapOf(
            Pair("123", true),
            Pair("123", false),
            Pair("123", true),
            Pair("123", true),
            Pair("123", true)
        )
        val observer = Mockito.mock(Observer::class.java) as Observer<Boolean>
        viewModel.isAllPermissionsGranted.observeForever(observer)
        viewModel.checkPermissions(permissions)
        assertFalse(viewModel.isAllPermissionsGranted.value!!)
    }
//Omitted
}

и вот моя ViewModel

class PermissionsViewModel : ViewModel() {
        var isAllPermissionsGranted = MutableLiveData<Boolean>().apply {
            value = null
        }

        fun checkPermissions(permissionsResult: HashMap<String, Boolean>) {
            var isAllPermissionsGranted = true
            permissionsResult.values.forEach { isGranted ->
                if (!isGranted) {
                    isAllPermissionsGranted = false
                    return@forEach
                }
            }
            this.isAllPermissionsGranted.postValue(isAllPermissionsGranted)
        }
    }

Тестирую ли я LiveData неправильно? Или есть проблемы с тестированием LiveData?

1 Ответ

0 голосов
/ 18 апреля 2019

Во-первых, я не уверен, что вы использовали эту хэш-карту для тестов, потому что у нее были те же ключи, поэтому она, вероятно, использовала бы последнюю пару. Во-вторых, для живых данных (потому что они асинхронные) я считаю использование блокирования наблюдаемого расширения очень полезным. Вот рабочий код с блокируемым наблюдаемым расширением:

class PermissionsViewModelTest{
@get:Rule
var rule: TestRule = InstantTaskExecutorRule()
lateinit var viewModel: PermissionsViewModel
@Before
fun setUp() {
    viewModel = PermissionsViewModel()
}

//Omited

@Test
fun `Should post false if permissions is not granted`() {
    val permissions = hashMapOf(
            Pair("123", true),
            Pair("124", true),
            Pair("125", false),
            Pair("126", true),
            Pair("127", true)
    )
    val grantedObserver = viewModel.isAllPermissionsGranted
    viewModel.checkPermissions(permissions)
    val value = grantedObserver.blockingObserve() // extension below
    assertFalse(value!!)
    }

//Omited
}

class PermissionsViewModel : ViewModel() {
var isAllPermissionsGranted = MutableLiveData<Boolean>().apply {
    value = null
}

fun checkPermissions(permissionsResult: HashMap<String, Boolean>) {
    val isAllPermissionsGranted = permissionsResult.values.all{it}
    this.isAllPermissionsGranted.postValue(isAllPermissionsGranted)
    }
}

// blocking observe extension:
    fun <T> LiveData<T>.blockingObserve(): T? {
    var value: T? = null
    val latch = CountDownLatch(1)
        val innerObserver = Observer<T> {
        value = it
        latch.countDown()
    }
    observeForever(innerObserver)
    latch.await(2, TimeUnit.SECONDS)
    return value
}
...