Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AssertJ: what is the difference between containsOnly and containsExactlyInAnyOrder

AbstractIterableAssert#containsOnly says:

Verifies that the actual group contains only the given values and nothing else, in any order.

AbstractIterableAssert#containsExactlyInAnyOrder says:

Verifies that the actual group contains exactly the given values and nothing else, in any order.

The description looks almost the same, so what is actual difference between only and exactly?

like image 302
radistao Avatar asked Dec 27 '17 12:12

radistao


1 Answers

The actual difference is matter only if the expected and actual collections/lists contain duplicates:

  • containsOnly is always duplicates insensitive: it never fails if sets of expected/actual values are matched

  • containsExactlyInAnyOrder is always duplicates sensitive: it fails if the numbers of expected/actual elements are different

Although, they all fail if:

  • at least one expected unique value is missing in the actual collection

  • not every unique value from actual collection is asserted

See the example:

private List<String> withDuplicates;
private List<String> noDuplicates;

@Before
public void setUp() throws Exception {
    withDuplicates = asList("Entryway", "Underhalls", "The Gauntlet", "Underhalls", "Entryway");
    noDuplicates = asList("Entryway", "Underhalls", "The Gauntlet");
}

@Test
public void exactMatches_SUCCESS() throws Exception {
    // successes because these 4 cases are exact matches (bored cases)
    assertThat(withDuplicates).containsOnly("Entryway", "The Gauntlet", "Underhalls", "Entryway", "Underhalls"); // 1
    assertThat(withDuplicates).containsExactlyInAnyOrder("Entryway", "The Gauntlet", "Underhalls", "Entryway", "Underhalls"); // 2

    assertThat(noDuplicates).containsOnly("Entryway", "The Gauntlet", "Underhalls"); // 3
    assertThat(noDuplicates).containsExactlyInAnyOrder("Entryway", "The Gauntlet", "Underhalls"); // 4
}

@Test
public void duplicatesAreIgnored_SUCCESS() throws Exception {
    // successes because actual withDuplicates contains only 3 UNIQUE values
    assertThat(withDuplicates).containsOnly("Entryway", "The Gauntlet", "Underhalls"); // 5

    // successes because actual noDuplicates contains ANY of 5 expected values
    assertThat(noDuplicates).containsOnly("Entryway", "The Gauntlet", "Underhalls", "Entryway", "Underhalls"); // 6
}

@Test
public void duplicatesCauseFailure_FAIL() throws Exception {
    SoftAssertions.assertSoftly(softly -> {
        // fails because ["Underhalls", "Entryway"] are UNEXPECTED in actual withDuplicates collection
        softly.assertThat(withDuplicates).containsExactlyInAnyOrder("Entryway", "The Gauntlet", "Underhalls"); // 7

        // fails because ["Entryway", "Underhalls"] are MISSING in actual noDuplicates collection
        softly.assertThat(noDuplicates).containsExactlyInAnyOrder("Entryway", "The Gauntlet", "Underhalls", "Entryway", "Underhalls"); // 8
    });
}
like image 57
radistao Avatar answered Oct 22 '22 19:10

radistao