Android-使用NavigationComponent测试导航



我在使用NavigationComponent、Espresso和Mockito测试导航时遇到问题。我有一个简单的测试:

@Test
fun testNavigation(){
val mockNavController = mock(NavController::class.java)
val firstScenario = launchFragmentInContainer<FirstFragment>()
firstScenario.onFragment { fragment ->
Navigation.setViewNavController(fragment.requireView(), mockNavController)
}
val expectedBundle = bundleOf(ARG_A to true)
onView(withId(R.id.button)).perform(click())
verify(mockNavController).navigate(R.id.action_first_fragment_to_second_fragment, expectedBundle)
}

测试失败,出现以下错误:

Argument(s) are different! Wanted:
navController.navigate(
2131361850,
Bundle[{ARG_A=true}]
);
-> at FirstFragmentTest.testNavigation(FirstFragmentTest.kt:60)
Actual invocation has different arguments:
navController.navigate(
2131361850,
Bundle[{ARG_A=true}]
);
-> at FirstFragment$onViewCreated$2.onClick(FirstFragment.kt:67)

参数和id完全相同,唯一的区别是错误中的最后一行显示了调用单击的位置。此外,我的测试中的onClick((方法似乎甚至没有打开第二个片段。它只是停留在第一个片段上。

有人知道出了什么问题吗?提前感谢!

Bundle可以包含不同类型和大小的不同类型的信息。

Bundle类的equals方法只是通过引用比较两个对象的默认实现。

您必须自己进行比较,或者使用已批准的解决方案。

我发现了Bundle超类BaseBundle的一个静态方法,称为kindOfEquals:

/**
* Does a loose equality check between two given {@link BaseBundle} objects.
* Returns {@code true} if both are {@code null}, or if both are equal as per
* {@link #kindofEquals(BaseBundle)}
*
* @param a A {@link BaseBundle} object
* @param b Another {@link BaseBundle} to compare with a
* @return {@code true} if both are the same, {@code false} otherwise
*
* @see #kindofEquals(BaseBundle)
*
* @hide
*/
public static boolean kindofEquals(BaseBundle a, BaseBundle b) {
return (a == b) || (a != null && a.kindofEquals(b));
}

但因为它做了loose equality check,这可能不是期望的解决方案。

更新

BaseBundle不是公共的,但您仍然可以检查它的kindOfEquals实现,并以它为例。

最新更新