Выбор ответа Middle Тестирование спрашивают часто обновлено
Зачем Dispatchers.setMain в тестах
Вопрос
Почему юнит-тест ViewModel, использующей viewModelScope, падает с ошибкой про отсутствие Main dispatcher?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: viewModelScope использует Dispatchers.Main, на JVM его подменяют setMain. Dispatchers.Main на Android работает через Looper главного потока, а в JVM-тесте его нет, поэтому обращение бросает IllegalStateException. kotlinx-coroutines-test позволяет подменить его тестовым диспетчером, обычно в JUnit-правиле, и…
Варианты ответа
- ViewModel нельзя тестировать на JVM: её конструктор требует Application
- Тест надо запускать на эмуляторе, где у процесса есть главный Looper
- Нужно пометить тест
@MainThread, и JUnit запустит его в главном потоке viewModelScopeиспользуетDispatchers.Main, на JVM его подменяютsetMainправильный ответ
Разбор
Dispatchers.Main на Android работает через Looper главного потока, а в JVM-тесте его нет, поэтому обращение бросает IllegalStateException. kotlinx-coroutines-test позволяет подменить его тестовым диспетчером, обычно в JUnit-правиле, и сбросить через resetMain(). После этого ViewModel тестируется локально и быстро. Аннотация @MainThread это подсказка для Lint, она не создаёт диспетчер.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.