Integer 在 espresso 测试中的 launchFragmentInContainer 包中提供了 NPE

问题描述 投票:0回答:1

我有一个片段等待来自 args 的整数。代码本身工作正常,但是当我想为此片段编写 UI 测试时,它给了我一个

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)`
The line which this refers to is
`navController.setCurrentDestination(R.id.MyFragment)

我像这样初始化我的场景:

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

对于所有其他类型的参数,它都可以工作(字符串,自定义数据模型),但对于整数,它不与我合作。

有什么想法吗?

android android-espresso gui-testing
1个回答
0
投票

您还没有提供您的

launchFragmentInContainer
实现,但我会根据我当前的设置和片段经验来回答。这是我的实现(请注意,我们正在使用 Hilt,但它应该类似)。

inline fun <reified T : Fragment> launchFragmentInHiltContainer(
        fragmentArgs: Bundle? = null,
        themeResId: Int = R.style.AppTheme,
        fragmentFactory: FragmentFactory? = null,
        crossinline action: T.() -> Unit = {}
    ) {
        val mainActivityIntent = Intent.makeMainActivity(
            ComponentName(
                ApplicationProvider.getApplicationContext(),
                HiltTestActivity::class.java
            )
        ).putExtra(
            "androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
            themeResId
        )

        ActivityScenario.launch<HiltTestActivity>(mainActivityIntent).onActivity { activity ->
            fragmentFactory?.let {
                activity.supportFragmentManager.fragmentFactory = it
            }
            val fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
                Preconditions.checkNotNull(T::class.java.classLoader),
                T::class.java.name
            )
            fragment.arguments = fragmentArgs

            activity.supportFragmentManager.beginTransaction()
                .add(android.R.id.content, fragment, "")
                .commitNow()

            (fragment as T).action()
        }

    }

假设您想要启动一个名为

MyView
的特定片段,对于这个(以及每个片段),您应该有
MyViewArgs
(或类似)对象。然后就可以这样开始了:

val args = MyViewArgs(11111).toBundle()     
HiltFragmentUtil.launchFragmentInHiltContainer<MyView>(args)

通过这种方式,您可以按照片段期望的确切方式提供参数,因此如果参数是 int,那么

MyViewArgs
将需要它作为 int

© www.soinside.com 2019 - 2024. All rights reserved.