Android测试报错:Navigation destination非NavGraph直接子节点,求助解决
问题分析与解决方案
核心问题
测试报错的原因有两个关键点:
- 无效的启动目的地:你在测试中设置的
startDestination = Screens.BREAKDOWNSUMMARY(不带参数的路径),在NavHost中并没有对应的composable节点——你只注册了带参数的Screens.BREAKDOWNSUMMARY.screenName + "/{Id}",这个不存在的启动目的地会导致NavGraph初始化异常,进而触发导航错误。 - 导航时机过早:测试中直接在
setContent块内调用navController.navigate,此时NavHost可能还未完成初始化,导航动作无法正确绑定到NavGraph。
代码修正方案
1. 调整NavHost的目的地注册(可选,支持参数可选)
如果需要同时支持带参数和不带参数的跳转,可将参数设为可选,同时简化参数处理逻辑:
// NavHostProvider.kt NavHost(navController = navController, startDestination = startDestination.screenName) { composable(Screens.BREAKDOWNSUMMARY.screenName + "/{Id}?") { // 添加?标记参数可选 val breakdownSummaryViewModel: BreakdownSummaryViewModel = hiltViewModel() val id = it.arguments?.getString("Id").orEmpty() breakdownSummaryViewModel.uiState.value.uldId = id BreakdownSummaryScreen( navController, breakdownSummaryViewModel, headerViewModel, lightHeaderViewModel, id ) } }
2. 修正测试代码
- 使用真实存在的带参数路径作为启动目的地,确保NavGraph初始化正常;
- 用
LaunchedEffect包裹导航代码,确保在Composable初始化完成后执行跳转:
// BreakdownSummaryViewModel.kt @Before fun launchComposable() { lightHeaderDataSource.addLightInfoToHeader("DL0558", "15", "06JUN2023") val testId = "test_uld_id" // 替换为实际测试用ID composeTestRule.setContent { val navController = rememberNavController() NavHostProvider.ArrivalsNavHostApp( navController, startDestination = Screens.BREAKDOWNSUMMARY.screenName + "/$testId" ) // 如果需要从其他页面导航到目标页,用LaunchedEffect确保时机正确 // LaunchedEffect(Unit) { // navController.navigate(Screens.BREAKDOWNSUMMARY.screenName + "/$testId") // } } }
额外检查点
- 确认
NavHostProvider.ArrivalsNavHostApp函数内确实包含了上述带参数的composable注册,没有路径拼写错误; - 测试中使用的
Id变量需提前赋值,避免空值导致路径拼接异常。
内容的提问来源于stack exchange,提问作者Anshul Tyagi
相关产品推荐
相关产品推荐

