Search code examples
javakotlinjunit5kotest

Assert that list contains elements with specific properties in any order


In Junit5 i used the following snippet often to test if a collection contains elements that fullfill certain criteria:

assertThat("The list of addresses", addresses.getAddressReferences(), containsInAnyOrder(
        allOf(
            hasProperty("id", is("abc")),
            hasProperty("role", is(SENDER))
        ),
        allOf(
            hasProperty("id", is("def")),
            hasProperty("role", is(RECEIVER))
        )
    ));

I did not yet find a way to express this in kotest I tried shouldContainExactlyInAnyOrder and such but they expect an actual object. I don't know how to express that i want to test each element against a different matcher.

I also checked the inspectors which might be the solution but they only seem to help to make assertions on ALL elements in the list at once.


Solution

  • Kotest Inspectors might be what you are looking for. They allow to test that all, none, or a specific number of elements in a collection satisfy specific assertions.

    Without knowledge of the address references data types I would assume that your example can be translated to Kotest like this:

    withClue("The list of addresses") {
        val references = addresses.getAddressReferences()
        assertSoftly {
            references shouldHaveSize 2
            references.forOne {
                it.id shouldBe "abc"
                it.role shouldBe SENDER
            }
            references.forOne {
                it.id shouldBe "def"
                it.role shouldBe RECEIVER
            }
        }
    }
    

    As pointed out by @LeoColman, the withClue and assertSoftly are not mandatory:

    • withClue just adds the given clue as additional info to the assertion error message in case an assertion fails.
    • assertSoftly lets all of the assertions inside it run instead of stopping at the first failed assertion. This means that if we have for instance a collection of 3 elements, we still get information about the fact that there is or is not an element with id "abc" and role SENDER.