Sunday, 17 April 2022

Testing Navigation from ActionBar menu

I am trying to write a test for a menu item. The idea is to click on the menu item and verify that the NavController is set to the correct destination:

public class NavigationTest {
    @Test
    public void clickOnSearchMenuNavigatesToFilter() {
        TestNavHostController navController = new TestNavHostController(ApplicationProvider.getApplicationContext());
        ActivityScenario<MainActivity> listScenario = ActivityScenario.launch(MainActivity.class);
        listScenario.onActivity(activity -> {
            navController.setGraph(R.navigation.nav_graph);
            Navigation.setViewNavController(activity.requireViewById(R.id.nav_host_fragment), navController);
        });
        Espresso.onView(ViewMatchers.withId(R.id.filter_menu)).perform(ViewActions.click());
        assertThat(Objects.requireNonNull(navController.getCurrentDestination()).getId()).isEqualTo(R.id.filter_cards);
    }
}

This test fails with

expected: 2131296468

but was : 2131296378

2131296378 is the id for the initial fragment in the NavController. What is wrong with my test? My initial thinking is that I am not injecting the TestNavHostController correctly, but debugging verified that the activity sees it as I expect:

public class MainActivity extends AppCompatActivity {
    // ...

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.onNavDestinationSelected(item, navController)
            || super.onOptionsItemSelected(item);
    }
}

When I set a breakpoint here, I confirm that navController is an instance of TestNavHostController.

For completeness, here's my nav_graph.xml:

<?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" />
        <action
            android:id="@+id/action_filter"
            app:destination="@id/filter_cards" />
        <argument
            android:name="filterParams"
            app:argType="android.os.Bundle"
            app:nullable="true" />
    </fragment>
    <fragment
        android:id="@+id/about"
        android:name="bbct.android.common.fragment.About"
        android:label="@string/about_title"
        tools:layout="@layout/about" />
    <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>
    <fragment
        android:id="@+id/filter_cards"
        android:name="bbct.android.common.fragment.FilterCards"
        android:label="@string/filter_cards_title"
        tools:layout="@layout/filter_cards">
        <action
            android:id="@+id/action_list"
            app:destination="@id/card_list" />
    </fragment>
    <action
        android:id="@+id/action_about"
        app:destination="@id/about" />
</navigation>

Any ideas what I am missing or anything I can try to troubleshoot this test?



from Testing Navigation from ActionBar menu

No comments:

Post a Comment