下面我有一個測驗類,旨在單獨啟動一個片段并測驗 navController 的導航能力。
第一次測驗,landingToGameFragmentTest()完美運行!
第二個測驗啟動一個片段,該片段取決于要傳遞給它的安全引數。除此之外,我認為它們的執行方式沒有任何區別。
// Declare navController at top level so it can be accessed from any test in the class
private lateinit var navController: TestNavHostController
// Use Generic type with fragment as upper bound to pass any type of FragmentScenario
private fun <T : Fragment> init(scenario: FragmentScenario<T>) {
// Create a test navController
navController = TestNavHostController(
ApplicationProvider.getApplicationContext()
)
scenario.onFragment { fragment ->
// Link navController to its graph
navController.setGraph(R.navigation.nav_graph)
// Link fragment to its navController
Navigation.setViewNavController(fragment.requireView(), navController)
}
}
@Test
fun landingToGameFragmentTest() {
init(launchFragmentInContainer<LandingFragment>(themeResId = THEME))
// Click button to navigate to GameFragment
onView(withId(R.id.button_start_game))
.perform(click())
assertEquals("Navigation to GameFragment failed",
R.id.gameFragment,
navController.currentDestination?.id)
}
@Test
fun gameToLandingFragmentTest() {
init(launchFragmentInContainer<GameFragment>(themeResId = THEME, fragmentArgs = Bundle()))
onView(withId(R.id.button_end_game))
.perform(click())
assertEquals("Navigation to LandingFragment failed",
R.id.landingFragment,
navController.currentDestination?.id)
}
我為其引數設定了一個默認值,但我仍然得到一個空引數例外,直到我傳遞一個空包。現在片段將啟動,但似乎無法導航到任何其他片段!
我在 SO 上找不到類似的問題,堆疊輸出超出了我的范圍。
在這init(launchFragmentInContainer())行之后,我逐步瀏覽了代碼,發現這拋出了一個illegalArgumentException:
public static int parseInt(@RecentlyNonNull String s, int radix) throws NumberFormatException {
throw new RuntimeException("Stub!");
}
Which then leads to getNavigator(), which passes the name "fragment".
However the only navigators are "navigation" and "test", of which I believe it should be test.
The illegalStateException is then thrown:
/**
* Retrieves a registered [Navigator] by name.
*
* @param name name of the navigator to return
* @return the registered navigator with the given name
*
* @throws IllegalStateException if the Navigator has not been added
*
* @see NavigatorProvider.addNavigator
*/
@Suppress("UNCHECKED_CAST")
@CallSuper
public open fun <T : Navigator<*>> getNavigator(name: String): T {
require(validateName(name)) { "navigator name cannot be an empty string" }
val navigator = _navigators[name]
?: throw IllegalStateException(
"Could not find Navigator with name \"$name\". You must call "
"NavController.addNavigator() for each navigation type."
)
return navigator as T
}
Finally navigate() is called on onView(withId(R.id.button_end_game)) generating:

I likely don't have to keep this test in this specific instance. However, I certainly will need to know how to launch a Fragment in isolation (that depends on safe args) in the future.
Thank you for your consideration!!
uj5u.com熱心網友回復:
您在這里有兩個完全不同的問題:
您的 Fragment 需要將引數傳遞給它。
引數通過Fragment testing guide中解釋的fragmentArgs引數傳遞給您的片段。launchFragmentInContainer
每個 Args 類(例如您的LandingFragmentArgs)都有一個建構式,可讓您Args直接構造該類。然后,您可以使用該toBundle()方法制作Bundle您傳遞給的launchFragmentInContainer:
val args = GameFragmentArgs(/* pass in your required args here */)
val bundle = args.toBundle()
init(launchFragmentInContainer<GameFragment>(fragmentArgs = bundle, themeResId = THEME))
您的 NavController 需要將其狀態設定為 GameFragment 目的地
您TestNavHostController不知道您的測驗需要從與關聯的目的地開始GameFragment- 默認情況下,它只會在startDestination您的圖表上(您嘗試觸發的任何操作都不存在)。
根據測驗導航檔案:
TestNavHostController提供了一種setCurrentDestination方法,允許您設定當前目的地,以便在測驗開始之前 NavController 處于正確狀態。
因此,您需要確保在通話setCurrentDestination后init撥打電話:
val args = GameFragmentArgs(/* pass in your required args here */)
val bundle = args.toBundle()
val scenario = launchFragmentInContainer<GameFragment>(fragmentArgs = bundle, themeResId = THEME)
init(scenario)
// Ensure that the NavController is set to the expected destination
// using the ID from your navigation graph associated with GameFragment
scenario.onFragment {
// Just like setGraph(), this needs to be called on the main thread
navController.setCurrentDestination(R.id.game_fragment, bundle)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/424641.html
標籤:android-fragments androidx android-navigation android-safe-args
下一篇:無法通過單擊影像替換片段
