Reputation: 83557
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)
2131296377
is the id for card_list
2131296378
is the id for card_details
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"
Upvotes: 1
Views: 566
Reputation: 200020
As per the Testing Navigation guide:
Just like a real
NavController
, you must callsetGraph
to initialize theTestNavHostController
. In this example, the fragment being tested was the start destination of our graph.TestNavHostController
provides asetCurrentDestination
method that allows you to set the current destination (and optionally, arguments for that destination) so that theNavController
is 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);
});
Upvotes: 2