I'm using the new Navigation Controller which is currently in alpha. It works fine but I can't find any documentation or sample app to see how testing is done. Also google published android.arch.navigation:navigation-testing
library for testing navigation but again there is no documentation.
Any help or suggestion will be appreciated.
Here a recent example of mine with a FragmentScenario
and 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"
}
And the instrumented test:
/**
* 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);
});
}
}
Such ->
Lambda expressions require compileOptions.sourceCompatibility JavaVersion.VERSION_1_8
set in the build.gradle
. And one can obtain the Activity
from fragment.getActivity()
(beware, it's not the usual one).
The official android documentation currently provides some detail but there aren’t a lot of examples.
In your test, you can provide a mock NavController using Mockito and can use it to verify your app's interactions.
For example, to test that the app properly navigates the user to a specific screen when the user clicks a button, your test needs to verify that this fragment invokes NavController.navigate()
with the desired action.
Using a combination of FragmentScenario, Espresso, and Mockito, you can recreate the conditions necessary to test this scenario, as shown below:
@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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With