Search code examples
javaandroidtestingjunithamcrest

Cannot resolve method 'assertThat(int)'


I'm following the Test Navigation docs that has the following test:

@RunWith(AndroidJUnit4.class)
public class TitleScreenTestJava {

    @Test
    public void testNavigationToInGameScreen() {

        // Create a TestNavHostController
        TestNavHostController navController = new TestNavHostController(
            ApplicationProvider.getApplicationContext());

        // Create a graphical FragmentScenario for the TitleScreen
        FragmentScenario<TitleScreen> titleScenario = FragmentScenario.launchInContainer(TitleScreen.class);

        titleScenario.onFragment(fragment ->
                // Set the graph on the TestNavHostController
                navController.setGraph(R.navigation.trivia);

                // Make the NavController available via the findNavController() APIs
                Navigation.setViewNavController(fragment.requireView(), navController)
        );

        // Verify that performing a click changes the NavController’s state
        onView(ViewMatchers.withId(R.id.play_btn)).perform(ViewActions.click());
        assertThat(navController.currentDestination.id).isEqualTo(R.id.in_game);
    }
}

First of all, this gives

Cannot resolve symbol 'currentDestination'

After some digging, I find getCurrentDestination(). I also have to change id to getId() to fix a similar error.

Then I get

Cannot resolve method 'assertThat(int)'

What version of assertThat() should I import? I found 2 versions in JUnit, but neither takes only one parameter. Besides both are deprecated. org.hamcrest.MatcherAssert has 3 versions of assertThat(), but again, none take a single int or Integer parameter. So where do I find the right version of assertThat()?

Beyond that, what am I missing here with all these changes I seem to be needed to fix the example from the official android docs? Or is this example broken?


Solution

  • This is from AssertJ library.
    Maven:

    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.22.0</version>
        <scope>test</scope>
    </dependency>
    

    AssertJ is a Java library that provides a rich set of assertions and truly helpful error messages, improves test code readability, and is designed to be super easy to use

    // basic assertions
    assertThat(frodo.getName()).isEqualTo("Frodo");
    assertThat(frodo).isNotEqualTo(sauron);
    

    See documentation assertThat(int)

    Update:
    I have reviewed more deeply android docs. Looks like Truth library (Maven repo) is used.
    Truth is the preferred library according to android docs and recommendations. It is part of Jetpack documentation.
    Jetpack is a suite of libraries to help developers follow best practices, reduce boilerplate code, and write code that works consistently across Android versions and devices so that developers can focus on the code they care about.


    See example of test with correct imports. Git
    Documentation about assertThat(Integer)

    AndroidX is an extension of Truth

    Other extensions that are not part of the Truth project itself include:

    • AndroidX Test for testing Android types, like Intent

    Setup project with AndroidX

        // Assertions
        androidTestImplementation "androidx.test.ext:junit:$testJunitVersion"
        androidTestImplementation "androidx.test.ext:truth:$truthVersion"
    

    Truth vs. AssertJ

    Truth and AssertJ are very similar. This raises the question: Why did we create Truth? The reason is historical: AssertJ didn’t exist when we started Truth. By the time it was created, we’d begun migrating Google code to Truth, and we’d made some design decisions that would be difficult to retrofit onto AssertJ.