2016-07-14 22 views
4

Ich habe ein Projekt, in dem ich Objekte als DTOs empfange und sie in View-Models umwandle. Um diese Konvertierung durchzuführen, habe ich mich entschieden, benutzerdefinierte Konverter zu erstellen, die einige Berechnungen durchführen, um von DTOs-Eigenschaften zu View-Modellen zu konvertieren. Nachdem alle fertig waren und die Konvertierung funktionierte, wollte ich der Konvertierung einige Komponententests hinzufügen, um sie stabiler zu machen (ich weiß, dass TDD nicht respektiert wird, aber das ist, was ich geschafft habe).Wie wird die Gleichheit zweier Objekte in Komponententests getestet?

Das Problem kommt, wenn ich Tests wollen die Gleichheit von zwei View-Modelle

Assert.AreEqual(expected, actual); 

Da keine der View-Modelle verifizieren Equals Methode definieren, und sie werden nie als Referenz gleich sein. Es gibt einige Ansätze, die ich darüber nachgedacht, und diese Objekte vergleichen gefunden:

  1. die Equals Methode zu definieren. Aber ich weiß nicht, ob es eine gute Praxis ist, sie nur zu Testzwecken zu definieren. Und wenn ich es definiere, wird es empfohlen, die GetHashCode Methode auch zu definieren, also denke ich nicht, dass diese Lösung die beste ist. Eine andere Möglichkeit, die ich mir vorgestellt habe, ist die Implementierung von IEqualityComparer<T> im Testprojekt, um die Vergleichslogik vom Hauptkonvertierungsprojekt zu isolieren oder sogar in ein drittes Projekt zu extrahieren, damit das Konvertierungsmodul es in Zukunft verwenden kann, wenn es nötig ist . Diese Implementierung sieht gut aus, aber ich weiß nicht, ob es sich lohnt, ein weiteres Projekt mit vielen Klassen hinzuzufügen, die ebenfalls getestet werden sollten.

  2. Der dritte Ansatz, den ich auf einer Stack Overflow question gefunden habe, die interessant aussieht, besteht darin, beide Objekte zu serialisieren und die Strings zu vergleichen. Das Problem ist, dass ich nicht weiß, ob dies eine gute Programmierung ist.

Welche davon wäre der beste Weg, um die Objekte zu vergleichen? Fehle ich einige Ansätze, die effizienter sein könnten?

Hinweis: Die View-Models sind komplexe Objekte, und ich kann die Art der Konvertierung in andere Technologien nicht ändern.

+0

Scheint so, als ob Sie bereits die Vor- und Nachteile skizziert haben - ich würde der Serialisierung nicht vertrauen, wenn sie nicht vom selben Typ sind - es gibt viele Gründe, warum zwei Typen mit denselben Eigenschaften anders serialisieren könnten. –

+0

@DStanley sie werden immer der gleiche Typ sein, oder so scheint es gerade jetzt, obwohl, wenn ich eine Methode mit generischen Typparameter mache, wie es ist "Equals" von "IEqualityComparer", die beide Objekte empfängt und anstelle des einfachen Vergleichs, zu Serialisieren Sie sie und geben Sie ihren String-Vergleich zurück? Wäre es so stabil genug? – meJustAndrew

+0

@DStanley Ich kann sehen, dass Sie diese Frage als zu weit gefasst gewählt haben, aber ich habe die Hilfe gelesen, was bedeutet, zu breit zu sein, und ich denke nicht, dass diese Frage in diesen Abschnitt passt, da es keine Antworten gibt verlangen, den Lochinhalt eines Buches oder nicht einmal wirklich lange Antworten zu weben. Bitte bedenken Sie, dass viele andere Programmierfragen mehrere Antworten haben können, die gut sind, aber keine davon macht sie * zu breit *. Vielen Dank! – meJustAndrew

Antwort

2

Ihre zweite Ansatz ist viel besser als die beiden anderen, weil es Tests spezifischen Code zusammen hält mit Unit-Tests, und auch weil Sie damit Ihre Definition dessen ändern können, was es bedeutet, dass zwei View-Models gleich sind.

Es lohnt sich jedoch kaum, Gleichheitsvergleiche in ein separates Projekt zu verschieben: Wenn Sie die Gleichheitsvergleichslogik verwenden möchten, können Sie sie auch in Ihre Objekte einfügen. Wenn es andererseits nur zum Testen gedacht ist, sollten Sie es zusammen mit den Tests aufbewahren (d. H. Verwenden Sie Ihren Ansatz # 1).

Der auf Serialisierung basierende Ansatz ist zu fragil, weil er auf einem nicht verwandten Merkmal beruht (d. H.Serialisierung), um das Feature zu testen, das Sie tatsächlich testen (d. h. Konvertierung).

3

Ich mag Fluent Assertions ShouldBeEquivalentTo Methode.

actual.ShouldBeEquivalentTo(expected); 

Standardmäßig ist diese „einfach funktioniert“, sowohl die Objekte angenommen Sie passieren sind strukturell gleichwertig, aber Sie können zusätzliche Argumente liefern anpassen, wie Sie es den Vergleich machen wollen. Zum Beispiel, wenn Sie die Äquivalenz von ein paar Stücke des Objekts nur überprüfen wollen, könnte man sagen:

actual.ShouldBeEquivalentTo(new { 
    expected.Name, 
    expected.Description, 
    expected.Code 
}, options => 
    options.ExcludingMissingMembers);