Как проверить взаимодействие с меню при тестировании фрагментов с помощью 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)
}