Как я могу протестировать объект данных в реальном времени в Android MVVM

#android #unit-testing #kotlin #mvvm #android-viewmodel

Вопрос:

Привет, я пытаюсь протестировать данные livedata, которые находятся в моей модели представления, я написал для тестирования, чтобы убедиться, что вызов репозитория был выполнен

как я могу проверить, является ли объект живых данных в этом случае, и какие дополнительные тестовые примеры я должен написать для этого кода в ViewModel

Спасибо Р

mainactivityviewмодель

 class MainActivityViewModel @Inject constructor(
    private val dataRepository: DataRepository
): ViewModel() {
    val _charactersLiveData = MutableLiveData<Result<ArrayList<Character>>>()
    val charactersLiveData: LiveData<Result<ArrayList<Character>>> = _charactersLiveData

    fun fetchCharacters() {
        viewModelScope.launch {
            _charactersLiveData.value = dataRepository.getCharacters()
        }
    }
}
 

mainactivityviewмодельтест

 @RunWith(MockitoJUnitRunner::class)
class MainActivityViewModelTest {

    @get:Rule
    val coroutineRule = MainCoroutineRule()

    @Mock
    private lateinit var dataRepository: DataRepository

    @InjectMocks
    private lateinit var mainActivityViewModel: MainActivityViewModel

    @Test
    fun fetchCharacters() {
        runBlockingTest {
            mainActivityViewModel.fetchCharacters()
            verify(dataRepository).getCharacters()
        }
    }
}
 

Комментарии:

1. Если LiveData ссылается на репозиторий, я бы проверил, вызывается ли функция в макете, что вы уже сделали. Следует отметить, что ViewModel должен ввести диспетчер в конструктор, чтобы вы могли использовать Main. Диспетчер в тесте, поэтому результаты возвращаются синхронно.

2. Не могли бы вы поделиться примером этого, пожалуйста

3. В этом бесплатном курсе есть обширный раздел, посвященный тестированию. Это LiveData также показывает, как протестировать: udacity.com/course/advanced-android-with-kotlin—ud940

Ответ №1:

Вы можете сослаться на эту статью: https://medium.com/androiddevelopers/unit-testing-livedata-and-other-common-observability-problems-bb477262eb04

Основная идея здесь заключается в следующем:

  • Издеваться dataRepository
  • При dataRepository вызове getCharacters() он должен возвращать значение тестирования. Например. listOf('a')
  • Выполнять mainActivityViewModel.fetchCharacters()
  • Ожидайте ценности ваших текущих данных
 assertEquals(mainActivityViewModel.charactersLiveData.getOrAwaitValue(), listOf('a'))
 

Ответ №2:

Попробуйте это, если возникнут какие-либо проблемы, дайте мне знать. Я попытался сделать это в соответствии с вашим классом и данными, но если вам нужно, то могут быть изменения.

 @RunWith(MockitoJUnitRunner::class)
class MainActivityViewModelTest {

@get:Rule
val coroutineRule = MainCoroutineRule()

@Mock
private lateinit var dataRepository: DataRepository

@InjectMocks
private lateinit var mainActivityViewModel: MainActivityViewModel

@Mock
private lateinit var dataObserver:  Observer<Result<List<Character>>>

@Test
fun fetchCharacters() {
    runBlockingTest {
        Mockito.`when`(datarepository).getcharacter()
        .thenreturn(Result.success(listOf(Character (
        Name=A,
        Type=hero))))
mainActivityViewModel.fetchCharacters()
mainActivityViewModel.charactersLiveData.observeForever(dataObserver)
Mockito.verify(dataRepository).getCharacters()
Mockito.verify(dataObserver).onChanged(Result.success(listOf(Character (
  Name=A,
  Type=hero))))
mainActivityViewModel.charactersLiveData.removeObserver(dataObserver)
            }
        }

}