AnswerBun.com

Android - Testing navigation with NavigationComponent

Stack Overflow Asked by SomeKoder on January 3, 2022

I’m having trouble testing my navigation with NavigationComponent, Espresso and Mockito. I have this simple test:

@Test
fun testNavigation(){

    val mockNavController = mock(NavController::class.java)

    val firstScenario = launchFragmentInContainer<FirstFragment>()

    firstScenario.onFragment { fragment ->
        Navigation.setViewNavController(fragment.requireView(), mockNavController)
    }

    val expectedBundle = bundleOf(ARG_A to true)

    onView(withId(R.id.button)).perform(click())

    verify(mockNavController).navigate(R.id.action_first_fragment_to_second_fragment, expectedBundle)
}

The test fails with this error:

Argument(s) are different! Wanted:
navController.navigate(
2131361850,
Bundle[{ARG_A=true}]
);
-> at FirstFragmentTest.testNavigation(FirstFragmentTest.kt:60)

Actual invocation has different arguments:
navController.navigate(
2131361850,
Bundle[{ARG_A=true}]
);
-> at FirstFragment$onViewCreated$2.onClick(FirstFragment.kt:67)

The arguments and id are exactly the same, the only difference is that last line in the error showing where the on click was invoked. Also, the onClick() method in my test doesn’t even seem to open the second fragment. It just stays on the first fragment.

Does someone know what’s going wrong?
Thanks in advance!

One Answer

Bundles can contain different kinds of information, of different types and sizes.

equals method of Bundle class is just default implementation that compares two objects by reference.

You'll have to implement comparison by yourself or use already approved solution.

I've found a static method of Bundle superclass BaseBundle called kindOfEquals:

/**
 * Does a loose equality check between two given {@link BaseBundle} objects.
 * Returns {@code true} if both are {@code null}, or if both are equal as per
 * {@link #kindofEquals(BaseBundle)}
 *
 * @param a A {@link BaseBundle} object
 * @param b Another {@link BaseBundle} to compare with a
 * @return {@code true} if both are the same, {@code false} otherwise
 *
 * @see #kindofEquals(BaseBundle)
 *
 * @hide
 */
public static boolean kindofEquals(BaseBundle a, BaseBundle b) {
    return (a == b) || (a != null && a.kindofEquals(b));
}

But because it does loose equality check that may be not the desired solution.

Update

BaseBundle is not public but you can still check its kindOfEquals implementation and take it as an example.

Answered by Jenea Vranceanu on January 3, 2022

Add your own answers!

Related Questions

How to print a column using awk command line and add header

3  Asked on November 4, 2020 by maskiin

     

Create repeated declaration

5  Asked on November 3, 2020 by ferenc-deak

   

Why is synchronizing a method not advisable?

3  Asked on November 2, 2020 by linus-jame

     

How to filter array of objecs with an object

3  Asked on October 31, 2020 by zkk

     

Trying to have c++ program quit by inputting a letter

2  Asked on October 29, 2020 by elizabethcampbell441

 

reload page from express using setInterval

2  Asked on October 24, 2020 by dwayne-jackson

       

Jquery .last() equivalence to Javascript

1  Asked on October 23, 2020 by divja-afsa

     

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP