Gibt es einen Hamcrest “für jeden” Matcher, der behauptet, dass alle Elemente einer Sammlung oder Iterable mit einem einzelnen spezifischen Matcher übereinstimmen?

Lesezeit: 3 Minuten

Benutzer-Avatar
E-Riz

Angenommen Collection oder Iterable von Artikeln, gibt es welche Matcher (oder eine Kombination von Matchern), die behaupten, dass jedes Element mit einem einzigen übereinstimmt Matcher?

Zum Beispiel bei diesem Artikeltyp:

public interface Person {
    public String getGender();
}

Ich möchte eine Behauptung schreiben, dass alle Elemente in einer Sammlung von Persons haben eine bestimmte gender Wert. Ich denke so etwas:

Iterable<Person> people = ...;
assertThat(people, each(hasProperty("gender", "Male")));

Gibt es eine Möglichkeit, dies zu tun, ohne die zu schreiben each Matcher selbst?

Benutzer-Avatar
Sotirios Delimanolis

Verwenden Sie die Every Matcher.

import org.hamcrest.beans.HasPropertyWithValue;
import org.hamcrest.core.Every;
import org.hamcrest.core.Is;
import org.junit.Assert;

Assert.assertThat(people, (Every.everyItem(HasPropertyWithValue.hasProperty("gender", Is.is("male")))));

Hamcrest bietet auch Matchers#everyItem als Abkürzung dazu Matcher.


Vollständiges Beispiel

@org.junit.Test
public void method() throws Exception {
    Iterable<Person> people = Arrays.asList(new Person(), new Person());
    Assert.assertThat(people, (Every.everyItem(HasPropertyWithValue.hasProperty("gender", Is.is("male")))));
}

public static class Person {
    String gender = "male";

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

  • Es scheint, dass Generika Probleme verursachen. Ich bekomme ein Kompilierungsproblem, weil assertThat() erwartet Argumenttypen T, Matcher<?super T> aber es wird Iterable<Person>, Matcher<Iterable<Object>>

    – E-Riz

    4. März 2015 um 18:11 Uhr


  • @E-Riz Ich habe mit einem vollständigen Beispiel aktualisiert. Wenn Ihre Frage anders ist, bearbeiten Sie bitte Ihre Frage, um sie einzuschließen.

    – Sotirios Delimanolis

    4. März 2015 um 18:53 Uhr


  • Ihr Beispiel hat immer noch das Generika-bezogene Kompilierungsproblem, aber nur, wenn es gegen JDK 7 kompiliert wird; Mit JDK 8 lässt es sich gut kompilieren. Mir war nicht bewusst, dass sich die Generika-Spezifikation zwischen 7 und 8 geändert hat, aber anscheinend haben sie erkannt, dass der Compiler dumm war, und es behoben.

    – E-Riz

    4. März 2015 um 19:04 Uhr

  • Um es für Java 7 kompilieren zu können, musste ich den hasProperty Matcher wie folgt deklarieren: HasPropertyWithValue.<Person>hasProperty("gender", is("Male")) was die Lesbarkeitsverbesserungen, die Hamcrest bieten soll, ziemlich zerstört 🙁

    – E-Riz

    4. März 2015 um 19:08 Uhr

  • Und darüber hinaus woohaaa, Reflektion und By-String-Zugriff. Ich finde das mega hässlich. Ich würde die Sammlung lieber manuell iterieren und “asserThat()” für “Person::getGender()” verwenden, als …

    – Geisterkatze

    2. August 2017 um 8:53 Uhr

IMHO ist das viel besser lesbar:

people.forEach(person -> Assert.assertThat(person.getGender()), Is.is("male"));

  • Das ist Anti-Pattern. Asserts sollten nicht innerhalb einer Schleife platziert werden.

    – Peter Mitrovic

    23. Januar 2020 um 10:58 Uhr


  • @PetarMitrovic Warum sollten Asserts nicht innerhalb der Schleife platziert werden?

    – Raghu

    22. Oktober 2020 um 5:05 Uhr

  • Einfach ausgedrückt, Sie werden nicht in der Lage sein, sich ein vollständiges Bild über die fehlgeschlagenen Assertionen zu machen, da der Test Runner aussteigen würde, sobald er auf die erste fehlgeschlagene Assertion trifft.

    – Peter Mitrovic

    23. Oktober 2020 um 13:08 Uhr

Lesbarer als die genehmigte Antwort und keine separaten Behauptungen in einer Schleife:

import static org.assertj.core.api.Assertions.assertThat;

assertThat(people).allMatch((person) -> {
  return person.gender.equals("male");
});

  • aber das ist nicht Hamcrest

    – bzw

    7. Januar um 14:09 Uhr

1171340cookie-checkGibt es einen Hamcrest “für jeden” Matcher, der behauptet, dass alle Elemente einer Sammlung oder Iterable mit einem einzelnen spezifischen Matcher übereinstimmen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy