You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Espresso测试中launchFragmentInContainer传Integer触发NPE问题

Integer参数UI测试触发NullPointerException的解决思路

业务代码中从参数获取Integer的Fragment运行正常,但编写UI测试时,调用TestNavHostController.setCurrentDestination(R.id.MyFragment)触发NullPointerException,报错栈如下:

java.lang.NullPointerException: null cannot be cast to non-null type kotlin.Int 
at androidx.navigation.NavType$Companion$IntType$1.get(NavType.kt:320) 
at androidx.navigation.NavType$Companion$IntType$1.get(NavType.kt:310) 
at androidx.navigation.NavArgument.verify(NavArgument.kt:76) 
at androidx.navigation.NavDestination.addInDefaultArgs(NavDestination.kt:603) 
at androidx.navigation.NavController.navigate(NavController.kt:1855) 
at androidx.navigation.NavController.handleDeepLink(NavController.kt:1414) 
at androidx.navigation.testing.TestNavHostController.setCurrentDestination(TestNavHostController.kt:51) 
at androidx.navigation.testing.TestNavHostController.setCurrentDestination$default(TestNavHostController.kt:47) 
at com.wolfpackdigital.extrakarte.base.BaseUITest.setupNavigation(BaseUITest.kt:130)

当前测试场景初始化代码:

val bundle = bundleOf(
   "myParam" to 3
)
scenario = launchFragmentInContainer(themeResId = R.style.AppTheme, fragmentArgs = bundle)

其他类型参数(如String、自定义数据模型)均可正常工作,仅Integer参数出现问题,解决思路如下:

问题根源

TestNavHostController.setCurrentDestination()方法会自动验证目标Fragment在导航图中定义的参数规则。如果你的MyFragment导航参数myParam被定义为非空Int类型,但调用setCurrentDestination时未传入该参数,导航组件会尝试用默认值(默认是null)填充,而Kotlin非空Int无法接受null,直接触发类型转换NPE。注意:launchFragmentInContainer传入的fragmentArgs是给Fragment实例的,和导航组件的参数验证逻辑是两个独立流程,无法覆盖导航参数的校验。

可行解决方案

1. 调用setCurrentDestination时传入参数bundle

直接在设置当前目的地时,带上符合要求的参数bundle,让导航组件通过参数校验:

val navArgs = bundleOf("myParam" to 3)
navController.setCurrentDestination(R.id.MyFragment, navArgs)

2. 调整导航图中参数的可空性(按需使用)

如果业务允许myParam为空,可以修改导航图中该参数的配置:

  • 在导航图XML中,给myParam添加android:defaultValue="@null",并设置app:nullable="true"
  • 或者在Kotlin的导航安全参数类中,将myParam定义为Int?(可空类型)
    但此方法可能违背业务需求,需谨慎评估。

3. 封装带参数的导航设置方法(优化复用)

如果多个测试用例都需要设置该目的地,可以在BaseUITest中封装一个方法,自动带上必填参数:

fun setupMyFragmentNavigation() {
    val navArgs = bundleOf("myParam" to 3)
    navController.setCurrentDestination(R.id.MyFragment, navArgs)
}

内容的提问来源于stack exchange,提问作者E. P.B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:33:25