Модульный тест - проверка фрагментов внутри ViewPager2 - PullRequest
0 голосов
/ 22 октября 2019

Я изо всех сил пытался выяснить, как проверить фрагменты внутри ViewPager2 в моем классе Test ... Цель моего теста - убедиться, что ViewPager2 имеет ожидаемые фрагменты.

Вот как я его настраивал (реализация):

// Implementation class
// fragmentViewPager is my ViewPager2
...

fun setupFragments(fragments:List<Fragment>) {
    fragmentCount = fragments.size

    fragmentViewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL

    fragmentViewPager.adapter = object : FragmentStateAdapter(this) {

        override fun getItemCount(): Int {
            return fragments.size
        }

        override fun createFragment(position: Int): Fragment {
            return fragments[position]
        }
    }

    fragmentViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
        override fun onPageSelected(position: Int) {
            super.onPageSelected(position)
            lastInteractedFragmentIndex = position
        }
    })
}

...

Поскольку я создаю его, передавая FragmentStateAdapter, я ожидал, что смогу вытащить тот же объект, чтобы я мог посмотретьдля классов Fragments для моего модульного теста, но адаптер ViewPager2 имеет тип RecyclerView.Adapter<RecyclerView.ViewHolder>

На самом деле мне удалось получить правильное количество фрагментов, но это все.

// Inside Test Class attempt #1
...
val adapter:RecyclerView.Adapter<RecyclerView.ViewHolder> = fragmentViewPager.adapter!!
assertEquals(3, adapter.itemCount)
...

Моя вторая попытка состояла в получении отображаемых фрагментов с помощью supportFragmentManager, который всегда возвращает фрагмент, отображаемый в данный момент ViewPager2 (Контекст: я показываю 1 фрагмент за раз)

Тогда я былдумая, что, возможно, я смогу провести пальцем влево по viewpager2, чтобы следующий фрагмент стал видимым, чтобы я мог повторить тот же трюк:

// Inside Test Class attempt #2
...
var myFragments = activity!!.supportFragmentManager.fragments
assertTrue(myFragments[0] is MyFirstFragment) // This assertion is correct

    val downEvent = MotionEvent.obtain(
            SystemClock.uptimeMillis(),
            SystemClock.uptimeMillis() + 100,
            MotionEvent.ACTION_DOWN,
            150f,
            150f,
            0
    )

    val upEvent = MotionEvent.obtain(
            SystemClock.uptimeMillis(),
            SystemClock.uptimeMillis() + 100,
            MotionEvent.ACTION_UP,
            0f,
            150f,
            0
    ) 

// I tried desperately in both activity and viewPager2 separately and both as once like this:

activity!!.dispatchTouchEvent(downEvent)
activity!!.dispatchTouchEvent(upEvent)

fragmentViewPager!!.dispatchTouchEvent(downEvent)
fragmentViewPager.dispatchTouchEvent(upEvent)

// If swipe was performed technically after pulling the fragments again using supportFragmentManager, the first one (and only one) should be the next fragment in the viewPager2

myFragments = activity!!.supportFragmentManager.fragments

assertTrue(myFragments[0] is MySecondFragment) // Wrong assertion, swipe did not work

И моя последняя и самая простая попытка была сделана jПросто измените выбранный элемент, как в старомодном viewPager (one):

// Inside Test Class attempt #3
...
fragmentViewPager.setCurrentItem(1) // Trying to change to position 1
...

Поступая так, я могу попытаться использовать ту же тактику в попытке №2, используя supportFragmentManager. К сожалению, делая это, тест полностью останавливается и никогда не заканчивается

Я также безуспешно пытаюсь поиграть с requestDisallowInterceptTouchEvent методом ViewPager2.

...