Weiß jemand, warum JUnit 4 Methoden anbietet, assertEquals(foo,bar)
aber keine assertNotEqual(foo,bar)
?
Es bietet assertNotSame
(entsprechend assertSame
) und assertFalse
(entsprechend assertTrue
), so dass es seltsam erscheint, dass sie sich nicht die Mühe gemacht haben, einzuschließen assertNotEqual
.
Ich weiß übrigens, dass JUnit-Addons die Methoden bieten, nach denen ich suche. Ich frage nur aus Neugier.
Antworten:
Ich würde vorschlagen, dass Sie die neueren
assertThat()
Stil-Asserts verwenden, die alle Arten von Negationen leicht beschreiben und automatisch eine Beschreibung dessen erstellen können, was Sie erwartet haben und was Sie erhalten haben, wenn die Assertion fehlschlägt:Alle drei Optionen sind gleichwertig. Wählen Sie die Option aus, die Sie am besten lesen können.
Um die einfachen Namen der Methoden zu verwenden (und diese angespannte Syntax funktionieren zu lassen), benötigen Sie diese Importe:
quelle
assertNotEquals()
.assertNotEqual
" würde ich sagen, dass dies eine spezialisierte Behauptung ist, die nicht so oft benötigt wirdassertEquals
und daher über das Generikum ausgedrückt wirdassertFalse
.assertThat
ist viel ausdrucksvoller als die begrenztenassert*
verfügbaren Methoden. Daher können Sie die genauen Einschränkungen in einer einzigen Zeile ausdrücken, sie (fast) wie einen englischen Satz lesen lassen und eine aussagekräftige Nachricht erhalten, wenn die Bestätigung fehlschlägt. Zugegeben, das ist nicht immer ein Killer-Feature, aber wenn Sie es ein paar Mal in Aktion gesehen haben, werden Sie sehen, wie viel Wert es hinzufügt.assertThat
ausdrucksvoller ist alsassert*
, aber ich denke nicht, dass es ausdrucksvoller ist als der Java-Ausdruck, den Sieassert*
im Allgemeinen in den Ausdruck hinein- und herausfügen können (schließlich kann ich alles in Java-Code ausdrücken). Es ist ein allgemeines Problem, auf das ich bei fließenden APIs gestoßen bin - jedes ist im Grunde ein neues DSL, das Sie lernen müssen (wenn wir alle bereits das Java kennen!). Ich nehme an, Hamcrest ist jetzt allgegenwärtig genug, da es vernünftig ist zu erwarten, dass die Leute es wissen. Ich werde ein Stück spielen ...assertNotEquals
In JUnit 4.11 gibt es eine : https://github.com/junit-team/junit/blob/master/doc/ReleaseNotes4.11.md#improvements-to-assert-and-assumequelle
Ich frage mich das auch. Die API von Assert ist nicht sehr symmetrisch. Zum Testen, ob Objekte identisch sind, wird Folgendes bereitgestellt
assertSame
undassertNotSame
.Natürlich ist es nicht zu lang zu schreiben:
Bei einer solchen Behauptung ist der einzige informative Teil der Ausgabe leider der Name der Testmethode, daher sollte eine beschreibende Nachricht separat gebildet werden:
Das ist natürlich so langweilig, dass es besser ist, selbst zu rollen
assertNotEqual
. Zum Glück wird es in Zukunft vielleicht Teil der JUnit: JUnit-Ausgabe 22 seinquelle
Ich würde argumentieren, dass das Fehlen von assertNotEqual in der Tat eine Asymmetrie darstellt und JUnit etwas weniger lernbar macht. Beachten Sie, dass dies ein guter Fall ist, wenn das Hinzufügen einer Methode die Komplexität der API verringern würde, zumindest für mich: Symmetrie hilft dabei, den größeren Raum zu regieren. Ich vermute, dass der Grund für die Auslassung darin liegen könnte, dass zu wenige Leute nach der Methode rufen. Ich erinnere mich jedoch an eine Zeit, als es nicht einmal AssertFalse gab. Daher habe ich eine positive Erwartung, dass die Methode irgendwann hinzugefügt werden könnte, da es keine schwierige ist. obwohl ich anerkenne, dass es zahlreiche Problemumgehungen gibt, sogar elegante.
quelle
Ich komme ziemlich spät zu dieser Party, aber ich habe festgestellt, dass die Form:
kann für die meisten "nicht gleich" Fälle gemacht werden.
quelle
Ich arbeite an JUnit in einer Java 8-Umgebung mit jUnit4.12
Für mich: Der Compiler konnte die Methode assertNotEquals nicht finden, selbst wenn ich sie verwendet habe
import org.junit.Assert;
Also wechselte ich
assertNotEquals("addb", string);
zu
Assert.assertNotEquals("addb", string);
Wenn Sie also auf ein Problem stoßen, das
assertNotEqual
nicht erkannt wurde, ändern SieAssert.assertNotEquals(,);
es in, um Ihr Problem zu lösenquelle
import static org.junit.Assert.*;
und Sie können alle Asserts ohne den Klassennamen verwenden.Der offensichtliche Grund, warum Leute assertNotEquals () wollten, war, eingebaute Objekte zu vergleichen, ohne sie zuerst in vollständige Objekte konvertieren zu müssen:
Ausführliches Beispiel:
vs.
Da Eclipse standardmäßig JUnit 4.11 nicht enthält, müssen Sie leider ausführlich sein.
Vorsichtsmaßnahme Ich glaube nicht, dass die '1' in eine Integer.valueOf () eingeschlossen werden muss, aber da ich neu von .NET zurückgekehrt bin, kann ich nicht auf meine Richtigkeit zählen.
quelle
Es ist besser, das Hamcrest für negative Behauptungen zu verwenden, als assertFalse, da im ersten Bericht der Testbericht einen Unterschied für den Assertionsfehler zeigt.
Wenn Sie assertFalse verwenden, wird im Bericht nur ein Assertionsfehler angezeigt. dh verlorene Informationen über die Fehlerursache.
quelle
Normalerweise mache ich das, wenn ich erwarte, dass zwei Objekte gleich sind:
und:
wenn erwartet wird, dass sie ungleich sind. Mir ist bewusst, dass dies keine Antwort auf Ihre Frage ist, aber es ist die nächste, die ich bekommen kann. Dies könnte anderen bei der Suche nach Möglichkeiten in JUnit-Versionen vor JUnit 4.11 helfen.
quelle
Ich stimme dem OP-Standpunkt voll und ganz zu.
Assert.assertFalse(expected.equals(actual))
ist kein natürlicher Weg, um eine Ungleichung auszudrücken.Aber ich würde argumentieren, dass weiter als
Assert.assertEquals()
,Assert.assertNotEquals()
funktioniert, aber nicht benutzerfreundlich ist, um zu dokumentieren, was der Test tatsächlich behauptet, und um zu verstehen / zu debuggen, wenn die Behauptung fehlschlägt.Also ja, JUnit 4.11 und JUnit 5 bieten
Assert.assertNotEquals()
(Assertions.assertNotEquals()
in JUnit 5), aber ich vermeide es wirklich, sie zu verwenden.Um den Status eines Objekts zu bestätigen, verwende ich im Allgemeinen eine Matcher-API, die sich leicht in den Objektstatus einfügt, die Absicht der Behauptungen klar dokumentiert und die sehr benutzerfreundlich ist, um die Ursache des Assertionsfehlers zu verstehen.
Hier ist ein Beispiel.
Angenommen, ich habe eine Tierklasse, in der ich die
createWithNewNameAndAge()
Methode testen möchte. Diese Methode erstellt ein neues Tierobjekt, indem es seinen Namen und sein Alter ändert, aber sein Lieblingsfutter beibehält.Angenommen, ich verwende
Assert.assertNotEquals()
, um zu behaupten, dass das ursprüngliche und das neue Objekt unterschiedlich sind.Hier ist die Tierklasse mit einer fehlerhaften Implementierung von
createWithNewNameAndAge()
:JUnit 4.11+ (oder JUnit 5) sowohl als Testläufer als auch als Assertion-Tool
Der Test schlägt wie erwartet fehl, aber die dem Entwickler angegebene Ursache ist wirklich nicht hilfreich. Es heißt nur, dass die Werte unterschiedlich sein sollten und das
toString()
Ergebnis ausgeben sollten, das für den tatsächlichenAnimal
Parameter aufgerufen wurde :Ok, die Objekte sind nicht gleich. Aber wo liegt das Problem?
Welches Feld wird in der getesteten Methode nicht richtig bewertet? Eins ? Zwei? Alle von ihnen ?
Um es zu entdecken, müssen Sie in der
createWithNewNameAndAge()
Implementierung graben / einen Debugger verwenden, während die Test-API viel freundlicher wäre, wenn sie für uns den Unterschied zwischen dem, was erwartet wird und dem, der erhalten wird, ausmachen würde.JUnit 4.11 als Test Runner und eine Test Matcher API als Assertion Tool
Hier das gleiche Testszenario, das jedoch AssertJ (eine hervorragende Test-Matcher-API) verwendet, um die Aussage über den
Animal
Status zu treffen ::Natürlich schlägt der Test immer noch fehl, aber diesmal ist der Grund klar angegeben:
Wir können lesen, dass
Animal::getName, Animal::getAge, Animal::getFavoriteFood
wir für Werte des zurückgegebenen Tieres diesen Wert erwarten:aber wir haben diese Werte gehabt:
Wir wissen also, wo untersucht wird:
name
undage
werden nicht richtig bewertet. Darüber hinaus ermöglicht die Tatsache, denhay
Wert in der Zusicherung von anzugeben,Animal::getFavoriteFood()
auch eine genauere Zusicherung der zurückgegebenenAnimal
. Wir möchten, dass die Objekte für einige Eigenschaften nicht gleich sind, aber nicht unbedingt für alle Eigenschaften.Die Verwendung einer Matcher-API ist also definitiv klarer und flexibler.
quelle
Die Modulo-API-Konsistenz, warum JUnit nicht
assertNotEquals()
bereitgestellt hat, ist der gleiche Grund, warum JUnit niemals Methoden wie bereitgestellt hatassertStringMatchesTheRegex(regex, str)
vs.assertStringDoesntMatchTheRegex(regex, str)
assertStringBeginsWith(prefix, str)
vs.assertStringDoesntBeginWith(prefix, str)
Das heißt, es gibt kein Ende, bestimmte Assertionsmethoden für die Art von Dingen bereitzustellen, die Sie in Ihrer Assertionslogik wünschen könnten!
Weit besser zusammensetzbare Test Primitiven , wie zur Verfügung zu stellen
equalTo(...)
,is(...)
,not(...)
,regex(...)
und lassen Sie den Programmierer Stück diejenigen zusammen , anstatt für mehr Lesbarkeit und geistige Gesundheit.quelle