AssertJ: what is the difference between containsOnly and containsExactlyInAnyOrder
Asked Answered
E

1

14

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?

Excrement answered 27/12, 2017 at 12:22 Comment(0)
E
22

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
    });
}
Excrement answered 27/12, 2017 at 12:22 Comment(3)
I was about to clarify that in containsOnly javadoc, one more reason to do it.Solipsism
done github.com/joel-costigliola/assertj-core/blob/…Solipsism
flawless explanation @ExcrementRiverhead

© 2022 - 2024 — McMap. All rights reserved.