Android Test пытается настроить инструментальные тесты для класса MyFragment, получает ошибки сборки, связанные с ViewMoAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Android Test пытается настроить инструментальные тесты для класса MyFragment, получает ошибки сборки, связанные с ViewMo

Сообщение Anonymous »

Я новичок в тестировании Android, и мне сложно заставить работать простые тесты из-за различных факторов.
Мой фрагмент, который я пытаюсь протестировать, имеет 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
}
}
Моя конечная цель — написать инструментированный androidTest на MyFragment; для проверки его полей ввода через привязку представления (что также является еще одной проблемой, которую я неоднократно видел в своих журналах неудач). Однако я не могу пройти этап компиляции, неоднократно просматривая журналы ошибок по различным проблемам. На данный момент я получаю:

Код: Выделить всё

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)
который срабатывает в строке, где ViewModelProvider пытается создать экземпляр с помощью findNavController() внутри фрагмента.
Вот мой текущий код для установки пройди тест:

Код: Выделить всё

@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)
}
}
}
Мне нужна помощь в выяснении того, как обойти IllegalStateException из-за того, что, очевидно, для navController не установлено значение ConstraintLayout (представления фрагмента через привязку представления). Я также не уверен, правильно ли я настраиваю тесты, потому что у меня также возникают проблемы с сбоем viewBinding с аналогичной проблемой, когда представление не возвращается в onCreateView до вызова фрагмента.requireView в настройке navController. код.
Любая помощь или указания в правильном направлении будут оценены по достоинству, поскольку я занимаюсь этим уже некоторое время без особого прогресса. Спасибо.

Подробнее здесь: https://stackoverflow.com/questions/790 ... getting-bu
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»