TL; DR
В этом ответе Robolectric используется для вызова платформы Android onCleared
на вашем ViewModel
. Этот способ тестирования медленнее, чем использование отражения (как в вопросе), и зависит как от Robolectric, так и от платформы Android. Этот компромисс зависит от вас.
Глядя на источник Android ...
... вы можете видеть, что ViewModel#onCleared
вызывается только в ViewModelStore
(для вашего ViewModels
). Это класс хранения для моделей представлений, который принадлежит ViewModelStoreOwner
классам, например, FragmentActivity
. Итак, когда ViewModelStore
вызывает onCleared
на вашем ViewModel
?
Он должен хранить ваше ViewModel
, затем магазин должен быть очищен (что вы не можете сделать самостоятельно).
Ваша модель вида сохраняется в ViewModelProvider
, когда вы get
ваш ViewModel
, используя ViewModelProviders.of(FragmentActivity activity).get(Class<T> modelClass)
, где T
- ваш класс модели представления. Он хранит его в ViewModelStore
из FragmentActivity
.
Магазин очищается, например, когда ваша активность фрагмента разрушена. Это связка звонков, которые идут повсюду, но в основном это:
- Есть
FragmentActivity
.
- Получите
ViewModelProvider
, используя ViewModelProviders#of
.
- Получите
ViewModel
, используя ViewModelProvider#get
.
- Уничтожь свою деятельность.
Теперь onCleared
должно быть вызвано на вашей модели представления. Давайте проверим это, используя Robolectric 4, JUnit 4, MockK 1.9:
- Добавьте
@RunWith(RobolectricTestRunner::class)
в свой тестовый класс.
- Создать контроллер активности, используя
Robolectric.buildActivity(FragmentActivity::class.java)
- Инициализируйте действие, используя
setup
на контроллере, это позволяет уничтожить его.
- Получить действие с помощью метода контроллера
get
.
- Получите вашу модель представления с шагами, описанными выше.
- Уничтожить действие, используя
destroy
на контроллере.
- Проверьте поведение
onCleared
.
Полный пример класса ...
... основываясь на примере вопроса:
@RunWith(RobolectricTestRunner::class)
class ViewModelOnClearedTest {
@Test
fun `MyViewModel#onCleared calls Object#function`() = mockkObject(Object) {
val controller = Robolectric.buildActivity(FragmentActivity::class.java).setup()
ViewModelProviders.of(controller.get()).get(MyViewModel::class.java)
controller.destroy()
verify { Object.function() }
}
}
class MyViewModel : ViewModel() {
override fun onCleared() = Object.function()
}
object Object {
fun function() {}
}