Проблема, с которой вы столкнулись, связана с изменением теней .
Когда вы пишете этот код
viewModel = mock(TrainingListViewModel::class.java)
val scenario = launchFragmentInContainer(themeResId = R.style.Theme_LafayWorkbook) {
TrainingListFragment().apply {
appExecutors = countingAppExecutors.appExecutors
viewModelFactory = ViewModelUtil.createFor(viewModel)
}
}
ViewModelUtil.createFor(viewModel)
означает , а не используя переменную viewModel
, которую вы создали с помощью mock
выше, но вместо этого используете переменную viewModel
** в вашем TrainingListFragment
. Это потому, что вы используете apply { }
, что означает, что область, к которой применяется код, является самим фрагментом - фактически, как если бы ваш код был внутри этого фрагмента, поэтому viewModel
действительно TrainingListViewModel.this.viewModel
.
Вот почему в вашем сообщении об ошибке написано
at com.maximesarrato.lafayapp.ui.training.TrainingListFragment.getViewModel(Unknown Source:7)
at com.maximesarrato.lafayapp.ui.training.TrainingListFragmentTest$init$$inlined$launchFragmentInContainer$1.instantiate(FragmentScenario.kt:114)
Вы звоните getViewModel()
, т.е. получаете доступ к свойству viewModel
из вашего блока instantiate
.
Самый простой Решение состоит в том, чтобы просто использовать другое имя переменной для вашей фиктивной viewModel вместо того же имени viewModel
. Если бы оно было названо mockViewModel
, то при вызове ViewModelUtil.createFor(mockViewModel)
будет правильно сослаться на вашу фиктивную ViewModel, поскольку в вашем фрагменте не будет никакой переменной с таким же именем.
Другой вариант - использовать also
вместо apply
:
viewModel = mock(TrainingListViewModel::class.java)
val scenario = launchFragmentInContainer(themeResId = R.style.Theme_LafayWorkbook) {
TrainingListFragment().also { fragment ->
fragment.appExecutors = countingAppExecutors.appExecutors
fragment.viewModelFactory = ViewModelUtil.createFor(viewModel)
}
}
also
, как и apply
, всегда возвращает исходный объект - ваш TrainingListFragment
(это правильно и то, что вы хотите вернуть).
Однако при использовании also
вам нужно назвать переменную, с которой вы работаете (здесь я использую fragment
вместо значения по умолчанию it
), и вам нужно специально использовать fragment.viewModel
, если вы хотите сослаться к чему-то внутри переменной фрагмента. Опять же, без тени имени, в этом случае viewModel
будет указывать на единственную viewModel
переменную в области видимости - вашу ложную ViewModel.