Ich versuche zu behaupten, dass ein Objekt einem anderen Objekt "gleich" ist.
Die Objekte sind nur Instanzen einer Klasse mit einer Reihe öffentlicher Eigenschaften. Gibt es eine einfache Möglichkeit, NUnit die Gleichheit basierend auf den Eigenschaften geltend machen zu lassen?
Dies ist meine aktuelle Lösung, aber ich denke, es gibt vielleicht etwas Besseres:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
Was ich anstrebe, wäre im gleichen Sinne wie die CollectionEquivalentConstraint, bei der NUnit überprüft, ob der Inhalt von zwei Sammlungen identisch ist.
quelle
IEnumerable
es unabhängig von überschreibenden Implementierungen als Sammlung verglichen,Equals
da NUnit eineIEnumerable
höhere Priorität hat.NUnitEqualityComparer.AreEqual
Einzelheiten finden Sie in den Methoden. Sie können den Vergleicher überschreiben, indem Sie eine derUsing()
Methoden der Gleichheitsbeschränkung verwenden. Selbst dann ist esIEqualityComparer
aufgrund des von NUnit verwendeten Adapters nicht ausreichend, das nicht generische zu implementieren .GetHashCode()
auf veränderlichen Typen verhält sich schlecht, wenn Sie dieses Objekt jemals als Schlüssel verwenden. IMHO, überschriebenEquals()
,GetHashCode()
und machen das Objekt unveränderlich nur für die Prüfung keinen Sinn macht.Wenn Sie Equals aus irgendeinem Grund nicht überschreiben können, können Sie eine Hilfsmethode erstellen, die öffentliche Eigenschaften durch Reflektion durchläuft und jede Eigenschaft bestätigt. Etwas wie das:
quelle
Überschreiben Sie Equals nicht nur zu Testzwecken. Es ist langwierig und wirkt sich auf die Domänenlogik aus. Stattdessen,
Verwenden Sie JSON, um die Daten des Objekts zu vergleichen
Keine zusätzliche Logik für Ihre Objekte. Keine zusätzlichen Aufgaben zum Testen.
Verwenden Sie einfach diese einfache Methode:
Es scheint großartig zu funktionieren. Die Informationen zu den Ergebnissen des Testläufers zeigen den enthaltenen JSON-Zeichenfolgenvergleich (das Objektdiagramm), sodass Sie direkt sehen, was falsch ist.
Beachten Sie auch! Wenn Sie größere komplexe Objekte haben und nur Teile davon vergleichen möchten, können Sie ( verwenden Sie LINQ für Sequenzdaten ) anonyme Objekte erstellen, die mit der obigen Methode verwendet werden können.
quelle
Probieren Sie die FluentAssertions-Bibliothek aus:
http://www.fluentassertions.com/
Es kann auch mit NuGet installiert werden.
quelle
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Ich ziehe es vor, Equals nicht zu überschreiben, nur um das Testen zu ermöglichen. Vergessen Sie nicht, dass Sie GetHashCode auch überschreiben sollten, wenn Sie Equals überschreiben. Andernfalls erhalten Sie möglicherweise unerwartete Ergebnisse, wenn Sie Ihre Objekte beispielsweise in einem Wörterbuch verwenden.
Ich mag den obigen Reflexionsansatz, da er das Hinzufügen von Eigenschaften in der Zukunft ermöglicht.
Für eine schnelle und einfache Lösung ist es jedoch oft am einfachsten, entweder eine Hilfsmethode zu erstellen, die prüft, ob die Objekte gleich sind, oder IEqualityComparer für eine Klasse zu implementieren, die Sie für Ihre Tests privat halten. Wenn Sie die IEqualityComparer-Lösung verwenden, müssen Sie sich nicht um die Implementierung von GetHashCode kümmern. Beispielsweise:
quelle
Ich habe verschiedene hier erwähnte Ansätze ausprobiert. In den meisten Fällen müssen Sie Ihre Objekte serialisieren und einen Zeichenfolgenvergleich durchführen. Obwohl es super einfach und im Allgemeinen sehr effektiv ist, habe ich festgestellt, dass es etwas zu kurz kommt, wenn Sie einen Fehler haben und so etwas gemeldet wird:
Herauszufinden, wo die Unterschiede liegen, ist gelinde gesagt ein Schmerz.
Mit FluentAssertions' Objektgraph - Vergleichen (dh
a.ShouldBeEquivalentTo(b)
), erhalten Sie diese zurück:Das ist viel schöner. Holen Sie sich jetzt FluentAssertions , Sie werden sich später freuen (und wenn Sie dies positiv bewerten, stimmen Sie bitte auch der Antwort von dkl zu, wo FluentAssertions zuerst vorgeschlagen wurde).
quelle
Ich stimme ChrisYoxall zu - die Implementierung von Equals in Ihrem Hauptcode nur zu Testzwecken ist nicht gut.
Wenn Sie Equals implementieren, weil es für eine Anwendungslogik erforderlich ist, ist das in Ordnung. Halten Sie jedoch reinen Nur-Test-Code von Unordnung fern (auch die Semantik der Überprüfung des gleichen Tests kann sich von der für Ihre App erforderlichen unterscheiden).
Kurz gesagt, halten Sie Testcode nur aus Ihrer Klasse heraus.
Ein einfacher flacher Vergleich von Eigenschaften mithilfe von Reflexion sollte für die meisten Klassen ausreichen, obwohl Sie möglicherweise eine Rekursion durchführen müssen, wenn Ihre Objekte komplexe Eigenschaften haben. Achten Sie bei folgenden Referenzen auf Zirkelverweise oder ähnliches.
Schlau
quelle
In NUnit 2.4.2 hinzugefügte Eigenschaftsbeschränkungen ermöglichen eine Lösung, die besser lesbar ist als die ursprüngliche des OP und viel bessere Fehlermeldungen erzeugt. Es ist in keiner Weise generisch, aber wenn Sie es nicht für zu viele Klassen tun müssen, ist es eine sehr adäquate Lösung.
Nicht so universell wie die Implementierung,
Equals
aber es gibt eine viel bessere Fehlermeldung alsquelle
Die JSON-Lösung von Max Wikstrom (oben) ist für mich am sinnvollsten. Sie ist kurz, sauber und funktioniert vor allem. Persönlich würde ich es jedoch vorziehen, die JSON-Konvertierung als separate Methode zu implementieren und die Bestätigung wie folgt wieder in den Komponententest einzufügen ...
HILFE-METHODE:
GERÄTETEST :
Zu Ihrer Information - Möglicherweise müssen Sie in Ihrer Lösung einen Verweis auf System.Web.Extensions hinzufügen.
quelle
Dies ist ein ziemlich alter Thread, aber ich habe mich gefragt, ob es einen Grund gibt, warum keine Antwort vorgeschlagen wurde
NUnit.Framework.Is.EqualTo
undNUnit.Framework.Is.NotEqualTo
?Sowie:
und
quelle
Eine weitere Option besteht darin, eine benutzerdefinierte Einschränkung durch Implementieren der abstrakten NUnit-
Constraint
Klasse zu schreiben . Mit einer Hilfsklasse, die ein wenig syntaktischen Zucker liefert, ist der resultierende Testcode angenehm knapp und lesbar, zBetrachten Sie als extremes Beispiel eine Klasse mit schreibgeschützten Mitgliedern,
IEquatable
und Sie können die zu testende Klasse nicht ändern, selbst wenn Sie Folgendes möchten:Der Vertrag für die
Constraint
Klasse erfordert eine ÜberschreibungMatches
undWriteDescriptionTo
(im Falle einer Nichtübereinstimmung eine Erzählung für den erwarteten Wert), aber auch eine ÜberschreibungWriteActualValueTo
(Erzählung für den tatsächlichen Wert) ist sinnvoll:Plus die Helferklasse:
Anwendungsbeispiel:
quelle
Ich würde auf der Antwort von @Juanma aufbauen. Ich bin jedoch der Meinung, dass dies nicht mit Unit-Test-Behauptungen implementiert werden sollte. Dies ist ein Dienstprogramm, das unter bestimmten Umständen von Nicht-Testcode verwendet werden kann.
Ich habe einen Artikel zu diesem Thema geschrieben: http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Mein Vorschlag lautet wie folgt:
Verwenden Sie dies mit NUnit
gibt die folgende Meldung bei Nichtübereinstimmung aus.
quelle
https://github.com/kbilsted/StatePrinter wurde speziell geschrieben, um Objektdiagramme in die Zeichenfolgendarstellung zu verschieben, um einfache Komponententests zu schreiben.
Gegeben
Sie können auf typsichere Weise und mithilfe der automatischen Vervollständigung von Visual Studio Felder ein- oder ausschließen.
quelle
Installieren Sie einfach ExpectedObjects von Nuget. Sie können auf einfache Weise den Eigenschaftswert von zwei Objekten, jeden Objektwert der Sammlung, den Wert von zwei zusammengesetzten Objekten und den Teilvergleich des Eigenschaftswerts nach anonymem Typ vergleichen.
Ich habe einige Beispiele für Github: https://github.com/hatelove/CompareObjectEquals
Hier sind einige Beispiele, die Szenarien zum Vergleichen von Objekten enthalten:
Referenz:
quelle
Schauen Sie sich den folgenden Link an. Es ist eine Lösung aus dem Code-Projekt und ich habe es auch verwendet. Es funktioniert gut zum Vergleichen der Objekte.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
quelle
Ich habe mit dem Schreiben einer einfachen Ausdrucksfabrik geendet:
und benutze es einfach:
Es ist sehr nützlich, da ich die Sammlung solcher Objekte vergleichen muss. Und Sie können diesen Vergleich woanders verwenden :)
Hier ist das Wesentliche mit einem Beispiel: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
quelle
Deserialisieren Sie beide Klassen und führen Sie einen Zeichenfolgenvergleich durch.
EDIT: Funktioniert perfekt, dies ist die Ausgabe, die ich von NUnit bekomme;
BEARBEITEN SIE ZWEI: Die beiden Objekte können identisch sein, aber die Reihenfolge, in der die Eigenschaften serialisiert werden, ist nicht dieselbe. Daher ist das XML anders. DOH!
EDIT THREE: Das funktioniert. Ich benutze es in meinen Tests. Sie müssen den Sammlungseigenschaften jedoch Elemente in der Reihenfolge hinzufügen, in der der zu testende Code sie hinzufügt.
quelle
Ich weiß, dass dies eine sehr alte Frage ist, aber NUnit hat immer noch keine native Unterstützung dafür. Wenn Sie jedoch Tests im BDD-Stil (ala Jasmine) mögen, werden Sie von NExpect ( https://github.com/fluffynuts/NExpect ) angenehm überrascht sein , erhalten Sie es von NuGet), in dem tiefgreifende Gleichheitstests sind .
(Haftungsausschluss: Ich bin der Autor von NExpect)
quelle
Stringifizieren und vergleichen Sie zwei Strings
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
quelle
quelle