2010-08-13 13 views
6

In einem Komponententest (in Visual Studio 2008) möchte ich den Inhalt eines großen Objekts (eine Liste von benutzerdefinierten Typen, um genau zu sein) vergleichen mit einer gespeicherten Referenz dieses Objekts. Das Ziel besteht darin, sicherzustellen, dass spätere Refactorings des Codes den gleichen Objekt-Inhalt erzeugen.(Deep) Vergleich eines Objekts mit einer Referenz in Komponententests (C#)

Verworfene Idee: Ein erster Gedanke war, in XML zu serialisieren und dann die hardcoded Zeichenfolgen oder einen Dateiinhalt zu vergleichen. Dies würde es ermöglichen, einen Unterschied leicht zu finden. Da meine Typen jedoch nicht ohne Hacker-XML serialisierbar sind, muss ich eine andere Lösung finden. Ich könnte die binäre Serialisierung verwenden, aber dies wird nicht mehr lesbar sein.

Gibt es eine einfache und elegante Lösung?

EDIT: Laut Marc GRA Vorschlag mache ich nun wie folgt aus:

using (MemoryStream stream = new MemoryStream()) 
     { 
      //create actual graph using only comparable properties 
      List<NavigationResult> comparableActual = (from item in sparsed 
                 select new NavigationResult 
                 { 
                  Direction = item.Direction, 
                  /*...*/ 
                  VersionIndication = item.VersionIndication 
                 }).ToList(); 

      (new BinaryFormatter()).Serialize(stream, comparableActual); 
      string base64encodedActual = System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length);//base64 encoded binary representation of this     
      string base64encodedReference = @"AAEAAAD....";//this reference is the expected value 
      Assert.AreEqual(base64encodedReference, base64encodedActual, "The comparable part of the sparsed set is not equal to the reference."); 
     } 

Im Wesentlichen ich zuerst die vergleichbare Eigenschaften zu tun wählen, dann die Grafik kodieren, vergleichen, es dann zu einem ähnlich kodierten Referenz. Codierung ermöglicht einen tiefen Vergleich auf einfache Weise. Der Grund, warum ich die Base64-Kodierung verwende, ist, dass ich den Verweis einfach in einer String-Variablen speichern kann.

+1

Die Serialisierungsidee scheint für tiefe Graphen gut zu sein. – StuartLC

+0

Serialisierung ist nicht vollständig zuverlässig. Sie könnten falsche Negative erhalten. Siehe http://stackoverflow.com/questions/2244223/is-it-reliable-to-compare-two-instances-of-a-class-by-comparing-their-serialized –

Antwort

5

Ich wäre immer noch geneigt, Serialisierung zu verwenden. Aber anstatt wissen, die Binärdatei, erstellen Sie einfach ein erwartetes Diagramm, serialisieren Sie das. Serialisieren Sie jetzt das tatsächliche Diagramm und vergleichen Sie die Bytes. Dies ist nur nützlich, um Ihnen zu sagen, dass ein Unterschied ist; Sie müssten Inspektion finden, was, was ein Schmerz ist.

+0

Ja, ich mache das gerade wie sagst du, aber ich will den Schmerz vermeiden! – Marcel

+0

So, jetzt fühle ich immer noch den Schmerz, aber mein Test funktioniert jetzt mit dem Schnitt in der Frage, so wie du es vorgeschlagen hast. – Marcel

+0

Vielleicht wird eine Kombination aus binärer Serialisierung und Deep Reflection-Analyse (wie in meiner Idee) im Falle von Mismatch im binären Vergleich lösen. – Migol

1

Ich würde den Hack verwenden, um XML-Vergleich zu machen. Oder Sie können die Reflektion verwenden, um Objekteigenschaften automatisch zu durchlaufen (aber dies durchläuft ALLE, auch einige, die Sie nicht möchten).

+0

Leider ist der Hack, um eine generierte Datei zu manipulieren (generiert von der Entität Framework) – Marcel

+0

Ist nicht Entity Framework Klassen teilweise generiert? Können Sie den "Hack" nicht in einer anderen Datei anwenden, indem Sie die Teilklassen nach Bedarf erweitern? Wenn Sie VS2010 verwenden, enthält es auch ADO.NET EntityObject Generator Vorlage. Dann können Sie die Entity Objects-Vorlage tatsächlich an Ihre Anforderungen anpassen. – FuleSnabel

1

Ich würde jeden benutzerdefinierten Typ erben IComparable, und bieten Gleichheit Methoden, die jeden benutzerdefinierten Typen vergleichen, sowie die Hauptklasse ICompareable machen, Sie können dann einfach vergleichen die 2 Objekte (wenn Sie sie im Speicher beim Ausführen haben Komponententests) Wenn nicht, würde ich vorschlagen, entweder serialisieren oder Konstanten definieren, die das refactored Objekt haben soll.

+0

Nun, es ist eine nette Lösung auch, wie es einige Funktionen zu Klassen auf Kosten des Schreibens von Code und mögliche Lecks hinzufügen (wenn ein Objekt IComparable nicht bieten, dann wird es nicht zuverlässig sein). – Migol

Verwandte Themen