Issue
I have the following navgraph with startDestination as card_list:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/card_list">
<fragment
android:id="@+id/card_list"
android:name="bbct.android.common.fragment.BaseballCardList"
android:label="@string/app_name"
tools:layout="@layout/card_list">
<action
android:id="@+id/action_details"
app:destination="@id/card_details" />
</fragment>
<fragment
android:id="@+id/card_details"
android:name="bbct.android.common.fragment.BaseballCardDetails"
android:label="@string/card_details_title"
tools:layout="@layout/card_details">
<argument
android:name="id"
app:argType="long" />
</fragment>
</navigation>
Now I want to write a test starting at card_details:
public class NavigationTest {
@Test
public void clickOnSaveNavigatesFromDetailsBackToList() {
TestNavHostController navController = new TestNavHostController(ApplicationProvider.getApplicationContext());
FragmentScenario<BaseballCardDetails> listScenario = FragmentScenario.launchInContainer(
BaseballCardDetails.class,
null,
R.style.AppTheme
);
listScenario.onFragment(fragment -> {
navController.setGraph(R.navigation.nav_graph);
Navigation.setViewNavController(fragment.requireView(), navController);
});
assertThat(Objects.requireNonNull(navController.getCurrentDestination()).getId())
.isEqualTo(R.id.card_details);
BaseballCard card = new BaseballCard(
true,
"Mint",
"Code Guru Apps",
1993,
"1",
50000,
1,
"Code Guru",
"Code Guru Devs",
"Catcher"
);
BBCTTestUtil.sendKeysToCardDetails(card);
Espresso.onView(ViewMatchers.withId(R.id.save_button)).perform(ViewActions.click());
assertThat(Objects.requireNonNull(navController.getCurrentDestination()).getId())
.isEqualTo(R.id.card_list);
}
}
This fails on
assertThat(Objects.requireNonNull(navController.getCurrentDestination()).getId())
.isEqualTo(R.id.card_details);
because the TestNavHostController is on the startDestination of card_list.
The actual failure message is
expected: 2131296377
but was : 2131296378
at bbct.android.common.navigation.NavigationTest.clickOnSaveNavigatesFromDetailsBackToList(NavigationTest.java:116)
2131296377is the id forcard_list2131296378is the id forcard_details- Line 116 is the previously mentioned
assertThat()
How do I force this test to start from the correct destination? Or is this not the correct way to write such a test? Am I supposed to write such a test by navigating to card_details first by performing the UI operations that a user would normally do?
Dependencies:
In case it matters, I have the following nav dependency versions:
navVersion = '2.4.2'
implementation "androidx.navigation:navigation-fragment:$navVersion"
implementation "androidx.navigation:navigation-ui:$navVersion"
Solution
As per the Testing Navigation guide:
Just like a real
NavController, you must callsetGraphto initialize theTestNavHostController. In this example, the fragment being tested was the start destination of our graph.TestNavHostControllerprovides asetCurrentDestinationmethod that allows you to set the current destination (and optionally, arguments for that destination) so that theNavControlleris in the correct state before your test begins.
So add a call to setCurrentDestination to initialize your test on a particular destination:
listScenario.onFragment(fragment -> {
navController.setGraph(R.navigation.nav_graph);
// Create arguments using Safe Args generated classes
// or construct the Bundle directly
BaseballCardDetailsArgs args = new BaseballCardDetailsArgs.Builder(0).build();
Bundle arguments = args.toBundle();
// Then set the current destination to your card_details
navController.setCurrentDestination(R.id.card_details, arguments);
Navigation.setViewNavController(fragment.requireView(), navController);
});
Answered By - ianhanniballake
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.