我正在使用目前处于alpha状态的新导航控制器。它工作正常,但我找不到任何文档或示例应用程序来查看测试是如何完成的。谷歌也发布了android.arch.navigation:navigation-testing
用于测试导航的库,但同样没有文档。
任何帮助或建议将不胜感激。
这是我最近的一个FragmentScenario
和TestNavHostController
的例子:
dependencies {
androidTestImplementation "androidx.navigation:navigation-testing:2.3.5"
implementation "androidx.navigation:navigation-fragment:2.3.5"
implementation "androidx.navigation:navigation-runtime:2.3.5"
}
和仪器化测试:
/**
* Instrumented Navigation Test
* @author Martin Zeitler
*/
@RunWith(AndroidJUnit4.class)
public class NavControllerTest {
@IdRes
private final int theme = R.style.Theme_AppCompat_DayNight;
@Test
public void testHomeFragmentToLoginFragment() {
Bundle args = new Bundle();
FragmentScenario<HomeFragment> navhostScenario = FragmentScenario.launchInContainer(HomeFragment.class, args, theme, Lifecycle.State.STARTED);
navhostScenario.onFragment(fragment -> {
// Create a NavController and set the NavController property on the fragment
assertNotNull(fragment.getActivity());
TestNavHostController navController = new TestNavHostController(fragment.getActivity());
fragment.getActivity().runOnUiThread(() -> navController.setGraph(R.navigation.nav_graph));
Navigation.setViewNavController(fragment.requireView(), navController);
// Then navigate
navController.navigate(R.id.action_homeFragment_to_loginFragment);
NavDestination destination = navController.getCurrentDestination();
assertNotNull(destination);
assertEquals(destination.getId(), R.id.loginFragment);
});
}
}
这种->
Lambda 表达式需要在build.gradle
中设置compileOptions.sourceCompatibility JavaVersion.VERSION_1_8
。人们可以从fragment.getActivity()
获得Activity
(请注意,这不是通常的)。
官方 android 文档目前提供了一些细节,但没有很多例子。
在测试中,您可以使用 Mockito 提供模拟导航控制器,并可以使用它来验证应用的交互。
例如,若要测试当用户单击按钮时应用是否正确将用户导航到特定屏幕,测试需要验证此片段是否使用所需的操作调用NavController.navigate()
。
结合使用 FragmentScenario、Espresso 和 Mockito,您可以重新创建测试此方案所需的条件,如下所示:
@RunWith(AndroidJUnit4::class)
class FirstScreenTest {
@Test
fun testNavigationToSecondScreen() {
// Create a mock NavController
val mockNavController = mock(NavController::class.java)
// Create a graphical FragmentScenario for the FirstScreen
val firstScenario = launchFragmentInContainer<FirstScreen>()
// Set the NavController property on the fragment
firstScenario.onFragment { fragment ->
Navigation.setViewNavController(fragment.requireView(), mockNavController)
}
// Verify that performing a click prompts the correct Navigation action
onView(ViewMatchers.withId(R.id.button)).perform(ViewActions.click())
verify(mockNavController).navigate(R.id.action_first_screen_to_second_screen)
}
}