141 votes

Comment affirmer qu'un Iterable contient des éléments avec une certaine propriété ?

Supposons que je veuille tester unitairement une méthode avec cette signature :

List<MyItem> getMyItems();

Supposons que MyItem est un Pojo qui a de nombreuses propriétés, dont l'une est "name" accessible via getName() .

Tout ce qui m'importe, c'est de vérifier que le List<MyItem> ou tout autre Iterable contient deux MyItem dont les "name" Les propriétés ont les valeurs suivantes "foo" y "bar" . Si d'autres propriétés ne correspondent pas, cela ne m'intéresse pas vraiment pour les besoins de ce test. Si les noms correspondent, c'est un test réussi.

J'aimerais qu'il s'agisse d'une seule ligne si possible. Voici une "pseudo-syntaxe" du genre de chose que je voudrais faire.

assert(listEntriesMatchInAnyOrder(myClass.getMyItems(), property("name"), new String[]{"foo", "bar"});

Est-ce que Hamcrest serait bon pour ce genre de chose ? Si oui, quelle serait exactement la version Hamcrest de ma pseudo-syntaxe ci-dessus ?

151voto

Kevin Pauli Points 1614

Merci à @Razvan qui m'a orienté dans la bonne direction. J'ai pu l'obtenir en une ligne et j'ai réussi à chasser les importations pour Hamcrest 1.3.

les importations :

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;

le code :

assertThat( myClass.getMyItems(), contains(
    hasProperty("name", is("foo")), 
    hasProperty("name", is("bar"))
));

56voto

Razvan Points 5094

Essayez :

assertThat(myClass.getMyItems(),
                          hasItem(hasProperty("YourProperty", is("YourValue"))));

55voto

Mario Eis Points 81

Ce n'est pas spécialement Hamcrest, mais je pense que cela vaut la peine d'être mentionné ici. Ce que j'utilise assez souvent dans Java8 est quelque chose comme :

assertTrue(myClass.getMyItems().stream().anyMatch(item -> "foo".equals(item.getName())));

(Modifié par la légère amélioration de Rodrigo Manyari. C'est un peu moins verbeux. Voir les commentaires).

C'est peut-être un peu plus difficile à lire, mais j'aime la sécurité de la typologie et du remaniement. C'est aussi cool pour tester plusieurs propriétés de bean en combinaison, par exemple avec une expression && de type java dans le filtre lambda.

52voto

davidh Points 107

AssertJ fournit une excellente fonctionnalité dans extracting() : vous pouvez passer Function pour extraire des champs. Il fournit une vérification au moment de la compilation.
Vous pourriez également affirmer la taille en premier facilement.

Cela donnerait :

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

Assertions.assertThat(myClass.getMyItems())
          .hasSize(2)
          .extracting(MyItem::getName)
          .containsExactlyInAnyOrder("foo", "bar"); 

containsExactlyInAnyOrder() affirme que la liste ne contient que ces valeurs, quel que soit l'ordre.

Pour affirmer que la liste contient ces valeurs quel que soit l'ordre mais qu'elle peut aussi contenir d'autres valeurs, utilisez contains() :

.contains("foo", "bar"); 

Remarque : pour affirmer plusieurs champs à partir d'éléments d'un fichier List Avec AssertJ, nous faisons cela en enveloppant les valeurs attendues pour chaque élément dans une balise tuple() fonction :

import static org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple;

Assertions.assertThat(myClass.getMyItems())
          .hasSize(2)
          .extracting(MyItem::getName, MyItem::getOtherValue)
          .containsExactlyInAnyOrder(
               tuple("foo", "OtherValueFoo"),
               tuple("bar", "OtherValueBar")
           );

30voto

Frank Neblung Points 911

Assertj est bon dans ce domaine.

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

    assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar");

Le gros avantage d'assertj par rapport à hamcrest est l'utilisation facile de la complétion de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X