#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)
}
}
}