Как проверить взаимодействие с меню при тестировании фрагментов с помощью FragmentScenario

Я пытаюсь протестировать фрагмент с помощью FragmentScenario. У этого фрагмента есть собственное меню. На панели действий есть значок добавления, и щелчок по этому пункту меню запускает дочерний фрагмент, из которого пользователь может добавлять новые элементы. Итак, я пытаюсь проверить это поведение. Однако, как вы, возможно, знаете, FragmentScenario запускает фрагмент в EmptyFragmentActivity без запуска реальной активности узла. Поскольку панель действий не является частью макета фрагмента, а принадлежит активности хоста, панель действий и, следовательно, меню даже не становятся видимыми во время тестирования. Итак, как я могу проверить взаимодействие с меню?

Я нашел эту информацию из официальных документов:

Если вам нужно вызвать метод самого фрагмента, например, чтобы ответить на выбор в меню параметров, вы можете сделать это безопасно, реализовав FragmentAction:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<MyFragment>()
        scenario.onFragment(fragment ->
            fragment.onOptionsItemSelected(clickedItem) {
                //Update fragment's state based on selected item.
            }
        }
    }
}

Однако как передать правильный элемент в обратный вызов onOptionsItemSelected? Я попытался определить addMenuItem как переменную-член и инициализировать его внутри onCreateOptionsMenu, но он возвращает значение null. onCreateOptionsMenu, похоже, не вызывается во время тестирования. Поэтому я не знаю, как тестировать взаимодействие пользователя с меню.

2 ответа

Решение

Я решил проблему, передав фиктивный пункт меню:

val scenario = launchFragmentInContainer<CategoryListFragment>(Bundle(), R.style.AppTheme)

//Create a dummy menu item with the desired item id.
val context: Context = ApplicationProvider.getApplicationContext<AndroidTestApplication>()
val addMenuItem = ActionMenuItem(context, 0, R.id.action_add, 0, 0, null)

 //Call onOptionsItemSelected with the dummy menu item
 scenario.onFragment { fragment ->
       fragment.onOptionsItemSelected(addMenuItem)
 }

Это работает, но если у кого-то есть лучшее / альтернативное решение, был бы рад услышать.

Вы также можете издеваться над пунктом меню, используя mockito. Что-то вроде этого:

      val menuItemMock = mock<ActionMenuItem> {
   on { itemId } doReturn R.id.action_item
}

       
launchFragmentInContainer { YourFragment().also{ /*initialize*/ } }
.onFragment {
    it.onOptionsItemSelected(menuItemMock)
}
Другие вопросы по тегам