Je teste une méthode pour voir si elle retourne la chaîne correcte. Cette chaîne est composée de beaucoup de lignes dont l'ordre peut changer, donnant ainsi généralement 2 combinaisons possibles. Cet ordre n'est pas important pour mon application.
Cependant, étant donné que l'ordre des lignes peut changer, l'écriture d'une instruction Assert ne fonctionnera pas, car elle réussira parfois le test et échouera parfois.
Alors, est-il possible d'écrire un test qui assertera une valeur de chaîne réelle contre 2 valeurs de chaîne attendues ou plus et verra si elle est égale à l'une d'elles?
Utilisation de Hamcrest CoreMatcher
(inclus dans JUnit 4.4 et versions ultérieures) et assertThat()
:
assertThat(myString, anyOf(is("value1"), is("value2"));
Je voudrais utiliser AssertJ pour cela:
assertThat("hello").isIn("hello", "world");
C'est plus concis et cela vous donnera un message descriptif lorsque l'assertion échoue.
Vous pouvez utiliser Hamcrest pour cela:
assertThat(testString, anyOf(
containsString("My first string"),
containsString("My other string")));
(Je vois que Joachim vient de répondre de manière très similaire (+1) ... je vais ajouter ceci comme autre exemple.)
Envisagez d’écrire un matcher hamcrest personnalisé renvoyé par une méthode, dans ce cas containsOneOf
, c’est-à-dire:
assertThat(myString, containsOneOf("value1", "value2"));
En accord avec les "modèles xUnit", vous devriez éviter la logique conditionnelle dans votre matcher, une boucle avec une instruction break devrait suffire.
Regardez Hamcrest et xUnit Patterns pour plus d'informations.
J'ai lu toutes les réponses, mais celle qui me semble la plus compacte et la plus expressive utilise la variable isOneOf
de Hamcrest, qui est déjà incluse dans JUnit.
assertThat(result, isOneOf("value1", "value2"));
ce qui vous donne un message d'erreur Nice en cas d'échec.
Java.lang.AssertionError:
Expected: one of {"value1", "value2"}
but: was "value"
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.Java:20)
[...]
J'utilise ce qui suit, j'espère que cela aiderait:
String expectedTitles[] = {"Expected1","Expected2"};
List<String> expectedTitlesList = Arrays.asList(expectedTitles);
assertTrue(expectedTitlesList.contains((actualTitle)));
Le plus simple/le plus efficace pourrait être
assert str.equals(result1) || str.equals(result2);
Cela n'aura effectivement pas de frais généraux lorsque les assertions ne sont pas activées.
Si le contenu d'une ligne est fixe, vous pouvez le scinder aux fins de ligne avant de procéder à la comparaison. Il vous suffit ensuite de comparer chaque ligne à un ensemble de valeurs attendues ...
Set<String> expectedValues = ...
String[] split = text.split("\n");
for(String str : split) {
assert(expectedValues.contains(str));
}
Si vous voulez vérifier que toutes les valeurs attendues sont présentes, vous pouvez affirmer que expectedValue.remove(str) == true
et affirmer après la boucle que le Set est vide. Si certaines lignes peuvent apparaître plusieurs fois, vous devez utiliser un sac au lieu d'un ensemble.
Si vous utilisez Junit, je ferais juste quelque chose comme ceci:
assertTrue(myString.equals("Value1") || myString.equals("Value"));
En supposant que la méthode testée retourne un tableau, vous pouvez tester en utilisant arrayContainingInAnyOrder de Hamcrest.
assertThat(result, is(arrayContainingInAnyOrder("value1", "value2", "value")))
Remarque: l’utilisation de l’emballage is
est purement facultative et n’est utilisée que comme sucre de lisibilité.
C'est un vieux post, mais je voulais avoir une réponse facile en natif, sans avoir à ajouter de bibliothèques supplémentaires. :)
Alors j'ai fait:
String e
e = "ear"
j = "jars"
assert (j == "jar" || e == "ear")
ou si vous voulez qu'ils soient vrais
assert (j == "jar" && e == "ear")