2014-12-22 6 views
19

Ich habe zwei Objekte A und B. Objekt A ist das tatsächliche Ergebnis, das ich während des JUnit-Tests erhalte. Objekt B Ich mache einen tatsächlichen End-DB-Aufruf und nehme wie erwartet die Überprüfung an. Ich muss bestätigen, dass zwei Objektinstanzen A und B in Wert gleich sind und nicht tatsächliche Objekt.Test zwei Instanzen von Objekt sind gleich JUnit

Wir haben eine Methode namens assertEquals(obj expected, obj actual) in JUnit, aber ich will nicht so.

Gibt es einen Weg oder Workaround, um das gleiche zu erreichen?

Antwort

1

Sie können jedes Mitglied dieser 2 Objekte geltend machen!

z.B. assertThat(actual).isEqualToComparingFieldByField(expected);

1

assertEquals() Aufrufe equals() auf Ihre Objekte, und es gibt keinen Weg darum herum. Was Sie tun können, ist, in Ihrer Klasse etwas wie public boolean like(MyClass b) zu implementieren, in dem Sie vergleichen würden, was Sie wollen. Dann können Sie das Ergebnis mit assertTrue(a.like(b)) überprüfen.

+1

Dies bedeutet, dass Ihr Produktionscode mit einem Verfahren verschmutzt rein für Test. Auch mit assertTrue erhalten Sie absolut keine Diagnose auf/warum/der Test ist fehlgeschlagen – tddmonkey

+0

Ich bin damit einverstanden, den Produktionscode mit Testcode verschmutzen, aber nicht auf die Diagnose, warum der Test fehlgeschlagen ist. Wenn es fehlgeschlagen ist, ist es fehlgeschlagen, weil tatsächliche Objekte nicht wie erwartet erwartet werden. Wenn Sie genauere Informationen wünschen, fügen Sie eine Reihe von Aussagen für jedes relevante Feld hinzu. –

+0

Die Diagnose, die Sie daraus erhalten, ist etwas wie "erwartet wahr: wurde falsch". Wenn Sie den Test ändern, um Assertionen besser zu nutzen, müssen Sie keine anderen Arbeiten ausführen.Wenn Sie meine Antwort sehen, werden alle Vorschläge eine Qualitätsdiagnose ergeben, die nicht nur anzeigt, dass der Test fehlgeschlagen ist, sondern auch warum – tddmonkey

1

Sie müssen die equals und für die gute Praxis hashCode Methode für Ihre Klasse überschreiben. Danach wird assertEquals(obj expected, obj actual) nicht als Referenz prüfen, sondern wird die Logik verwenden, die Sie in equals Methode implementiert haben.

+3

Ich betrachte diese sehr schlechte Praxis. Sie überschreiben Gleichgestellte nur, um einen Test zu erfüllen, der einen Feld-für-Feld-Vergleich erfordert. Wenn sich der equals-Vertrag später ändert, wird Ihr Test trotzdem bestehen, aber nicht grundlegend gebrochen. – tddmonkey

+1

@MrWiggles Wenn wir 2 Instanzen von Einige Klasse X haben, ist es nicht besser, eine anständige Implementierung von 'equal' zu haben Vergleichen Sie die Objekte, auf die wir uns verlassen können. equals Implementierung anstelle der Standard-'equals'-Implementierung von Object-Klasse geerbt. – sol4me

+1

Wenn Ihr Produktionscode den gleichen Wert benötigt, dann ja, zum Beispiel wenn Sie ihn in ein Set einfügen. Das Problem beim Überschreiben für eine Feldüberprüfung wie in diesem Fall ist, dass Sie eine Standard-equals-Implementierung durchführen, die jedes Feld überprüft. Wenn sich zu einem späteren Zeitpunkt die equals-Methode aus einem echten Geschäftsgrund ändern sollte, z. Vergleichen Sie nur die ID, der Test, der sie ursprünglich benötigt hat, ist jetzt defekt, wird aber nicht fehlschlagen. Auch, wenn Sie für diesen Test gleich verwenden, erhalten Sie keine diagnostischen Informationen darüber, warum die Objekte unterschiedlich sind, nur dass sie – tddmonkey

14

Denken Sie genau darüber nach, was Sie erreichen möchten. Möchten Sie die Objektidentität testen oder sicherstellen, dass die beiden Objekte genau dieselben Daten haben? Von deinem Vorschlag von assertEquals vermute ich, dass du Feld für Feld gehen willst.

Wenn die Objekte flach sind, können Sie

assertThat(actual, samePropertyValuesAs(expected)); 

verwenden Dies schlägt fehl, wenn das Objekt ein Verbund allerdings ist. Wenn Sie die gesamte Grafik gehen möchten, können Sie die sameBeanAs Matcher verwenden wir vor einiger Zeit schrieb dieses Problem zu beheben:

assertThat(actual, sameBeanAs(expected)); 

Wenn Sie mit AssertJ dann können Sie auch die integrierte Funktionalität wie folgt verwenden:

assertThat(actual).isEqualToComparingFieldByField(expected); 

Eine Sache, die Sie nicht wollen, es zu tun, die equals Methode dafür außer Kraft setzen, wie das könnte sich in Zukunft ändern Geschäftsanforderungen gerecht zu werden.

+0

Kennen Sie Hamcrest-Matcher, die wir verwenden können? – sol4me

+1

samePropertyValuesAs ist ein integrierter Hamcrest-Matcher. sameBeanAs ist ein benutzerdefinierter Hamcrest-Matcher, den wir bei Shazam geschrieben haben, um genau dieses Problem zu lösen. – tddmonkey

+0

Verwenden Sie assertThat (actual) .isEqualToComparingFieldByFieldRecursively (expected), wenn Sie ein Objekt im Objekt haben. – vis