Мой фрагмент, который я пытаюсь протестировать, имеет ViewModel, которая, насколько я понимаю, предоставляется Dagger (Not Hilt) с ленивым делегатом, переносящим navController из моего навигационного графа в метод ViewModelProvider для создания экземпляра для меня.
Код: Выделить всё
class MyFragment : Fragment() {
var _binding: FragmentMyBinding? = null
private val myViewModel: MyViewModel by lazy {
ViewModelProvider(findNavController().getBackStackEntry(R.id.nav_graph), Factory(this) { stateHandle ->
(activity as MainActivity).daggerComponent.myViewModel()
.create(stateHandle)}).get(MyViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentMyBinding.inflate(inflater, container, false)
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedCallback)
return _binding?.root
}
...//other omitted code
}
Код: Выделить всё
@Subcomponent
interface DaggerComponent {
@Subcomponent.Factory
interface Factory {
fun create(): DaggerComponent
}
fun myViewModel() : MyViewModel.MyViewModelFactory
fun inject(mainActivity: MainActivity)
}
Код: Выделить всё
class MyViewModel @AssistedInject constructor (
...//other dependencies injected omitted from this post
@Assisted val savedStateHandle : SavedStateHandle
) {
@AssistedFactory
interface MyViewModelFactory {
fun create(savedStateHandle: SavedStateHandle) : MyViewModel
}
}
Код: Выделить всё
java.lang.IllegalStateException: View androidx.constraintlayout.widget.ConstraintLayout{7ca4a60 V.E...... ......ID 0,0-0,0} does not have a NavController set
at androidx.navigation.Navigation.findNavController(Navigation.kt:71)
at androidx.navigation.fragment.NavHostFragment$Companion.findNavController(NavHostFragment.kt:386)
at androidx.navigation.fragment.FragmentKt.findNavController(Fragment.kt:29)
Вот мой текущий код для установки пройди тест:
Код: Выделить всё
@RunWith(AndroidJUnit4::class)
class MyFragmentTest {
@get:Rule
var activityRule = ActivityScenarioRule(MainActivity::class.java)
private lateinit var scenario: FragmentScenario
private lateinit var binding: FragmentMyBinding
private lateinit var navController : TestNavHostController
private lateinit var myViewModel: MyViewModel
@Before
fun setUp() {
navController = TestNavHostController(ApplicationProvider.getApplicationContext())
scenario = launchFragmentInContainer()
scenario.onFragment { fragment ->
navController.setGraph(R.navigation.nav_graph)
Navigation.setViewNavController(fragment.requireView(), navController)
binding = FragmentMyBinding.bind(fragment.requireView())
myViewModel = ViewModelProvider(navController.getBackStackEntry(R.navigation.nav_graph))[MyViewModel::class.java]
}
}
/* test for amount field showing edit text layout error based on current editText field text */
@Test
fun testErrorAmountField() {
scenario.moveToState(Lifecycle.State.RESUMED)
scenario.onFragment { fragment ->
val currencyFormatter = NumberFormat.getCurrencyInstance()
binding.amountEditText.setText(currencyFormatter.format(0.00))
assertEquals(fragment.getString(R.string.errorString), binding.amountEditText.error)
}
}
/* test for amount field showing no edit text layout error based on current editText field text */
@Test
fun testNoErrorAmountField() {
scenario.moveToState(Lifecycle.State.RESUMED)
scenario.onFragment { fragment ->
val currencyFormatter = NumberFormat.getCurrencyInstance()
binding.amountEditText.setText(currencyFormatter.format(1.00))
assertEquals(null, binding.amountEditText.error)
binding.amountEditText.setText(currencyFormatter.format(1000.00))
assertEquals(null, binding.amountEditText.error)
}
}
}
Любая помощь или указания в правильном направлении будут оценены по достоинству, поскольку я занимаюсь этим уже некоторое время без особого прогресса. Спасибо.
Подробнее здесь: https://stackoverflow.com/questions/790 ... getting-bu
Мобильная версия