Quand je regarde les exemples de la classe Assert JavaDoc
assertThat("Help! Integers don't work", 0, is(1)); // fails:
// failure message:
// Help! Integers don't work
// expected: is <1>
// got value: <0>
assertThat("Zero is one", 0, is(not(1))) // passes
Je ne vois pas un gros avantage sur, disons, assertEquals( 0, 1 )
.
C'est bien peut-être pour les messages si les constructions deviennent plus compliquées mais voyez-vous plus d'avantages? Lisibilité?
Il n'y a pas de gros avantage pour les cas où il existe un assertFoo
qui correspond exactement à votre intention. Dans ces cas, ils se comportent presque de la même manière.
Mais lorsque vous parlez de contrôles un peu plus complexes, l'avantage devient plus visible:
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
vs.
assertThat(foo, hasItems("someValue", "anotherValue"));
On peut déterminer lequel de ceux-ci est le plus facile à lire, mais une fois que l'assertion échoue, vous obtenez un bon message d'erreur de assertThat
, mais une quantité très minime d'informations provenant de assertTrue
.
assertThat
vous dira quelle était l'affirmation et ce que vous avez obtenu à la place. assertTrue
ne vous dira que que vous avez obtenu false
où vous vous attendiez true
.
JUnit notes de version pour la version 4.4 (où il a été introduit) présente quatre avantages:
- Plus lisible et typable: cette syntaxe vous permet de penser en termes de sujet, verbe, objet (assert "x est 3") plutôt que assertEquals , qui utilise un verbe, un objet et un sujet (affirmer "est égal à 3 x")
- Combinaisons: toutes les instructions correspondantes peuvent être annulées (, non (s) ), combinées ( non plus. ou (t) ), mappé sur une collection ( each (s) ), ou utilisé dans des combinaisons personnalisées ( afterFiveSeconds (s) )
- Messages d'échec lisibles. (...)
- Matchers personnalisés. En implémentant vous-même l'interface Matcher , vous pouvez obtenir tous les avantages ci-dessus pour vos propres assertions personnalisées.
Argumentation plus détaillée de l'homme qui a créé la nouvelle syntaxe: ici .
Fondamentalement pour augmenter la lisibilité du code .
Outre hamcrest, vous pouvez également utiliser les assertions de fest . Ils ont quelques avantages par rapport au hamcrest tels que:
assertEquals(123, actual); // reads "assert equals 123 is actual"
vsassertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
import static org.fest.assertions.api.Assertions.*;
// common assertions
assertThat(yoda).isInstanceOf(Jedi.class);
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
assertThat(frodo).isIn(fellowshipOfTheRing);
assertThat(sauron).isNotIn(fellowshipOfTheRing);
// String specific assertions
assertThat(frodo.getName()).startsWith("Fro").endsWith("do")
.isEqualToIgnoringCase("frodo");
// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.excludes(sauron);
// map specific assertions (One ring and elves ring bearers initialized before)
assertThat(ringBearers).hasSize(4)
.includes(entry(Ring.oneRing, frodo), entry(Ring.nenya, galadriel))
.excludes(entry(Ring.oneRing, aragorn));
Fest n'est plus actif, utilisez plutôt AssertJ .
Une justification de base est qu'il est difficile de gâcher la nouvelle syntaxe.
Supposons qu'une valeur particulière, foo, soit égale à 1 après un test.
assertEqual(1, foo);
--OU--
assertThat(foo, is(1));
Avec la première approche, il est très facile d'oublier le bon ordre et de le taper à l'envers. Ensuite, plutôt que de dire que le test a échoué car il s’attendait à 1 et 2, le message est inversé. Pas de problème lorsque le test réussit, mais peut entraîner une confusion lorsque le test échoue.
Avec la deuxième version, il est presque impossible de faire cette erreur.
Exemple:
assertThat(5 , allOf(greaterThan(1),lessThan(3)));
// Java.lang.AssertionError:
// Expected: (a value greater than <1> and a value less than <3>)
// got: <5>
assertTrue("Number not between 1 and 3!", 1 < 5 && 5 < 3);
// Java.lang.AssertionError: Number not between 1 and 3!
au fait: vous pouvez aussi écrire du texte dans assertXXX ...
assertThat(frodo.getName()).isEqualTo("Frodo");
Est proche du langage naturel.
Lecture plus facile, analyse plus facile du code. Le programmeur passe plus de temps à analyser le code qu'à en écrire un nouveau. Donc, si le code sera facile à analyser, le développeur devrait être plus productif.
P.S. Le code devrait être comme livre bien écrit. Code auto-documenté.
il y a des avantages à affirmerQue par rapport à assertEquals -
1) plus lisible
2) plus d'informations sur l'échec
3) Compiler les erreurs de temps - plutôt que les erreurs de temps d'exécution
4) souplesse dans la rédaction des conditions de test
5) portable - si vous utilisez hamcrest - vous pouvez utiliser jUnit ou TestNG comme infrastructure sous-jacente.