2010-08-13 6 views
6

En una prueba unitaria (en Visual Studio 2008) quiero comparar el contenido de un objeto grande (una lista de tipos personalizados, para ser precisos) con una referencia almacenada de este objeto. El objetivo es asegurarse de que cualquier refactorización posterior del código produzca el mismo contenido objeto.(Profunda) comparación de un objeto con una referencia en pruebas unitarias (C#)

Idea descartada: Una primera idea fue serializar en XML, y luego comparar las cadenas codificadas o el contenido de un archivo. Esto permitiría encontrar fácilmente cualquier diferencia. Sin embargo, dado que mis tipos no son XML serializables sin un truco, debo encontrar otra solución. Podría usar la serialización binaria, pero esto ya no será legible.

¿Existe una solución simple y elegante para esto?

EDIT: Según la propuesta de Marc Gravell hago ahora así:

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."); 
     } 

En esencia lo hago seleccionar las propiedades comparables en primer lugar, a continuación, codificar el gráfico, a continuación, lo comparan con una referencia codificada de manera similar. La codificación permite la comparación profunda de una manera simple. El motivo por el que uso la codificación base64 es que puedo almacenar fácilmente la referencia en una variable de cadena.

+1

La idea de serialización parece ser una buena para gráficos profundos. – StuartLC

+0

La serialización no es completamente confiable. Puedes obtener falsos negativos. Ver http://stackoverflow.com/questions/2244223/is-it-reliable-to-compare-two-instances-of-a-class-by-comparing-their-serialized –

Respuesta

5

Todavía estaría inclinado a utilizar la serialización. Pero en lugar de tener que saber el binario, simplemente cree un gráfico esperado, serializar eso. Ahora serialice el gráfico real y compare los bytes. Esto solo es útil para decirle que es una diferencia; necesitaría inspección para encontrar qué, lo cual es una molestia.

+0

Sí, actualmente estoy haciendo esto como dices, pero quiero evitar el dolor! – Marcel

+0

Así que ahora, todavía siento el dolor, pero mi prueba ahora funciona con la edición en la pregunta, haciéndolo como usted propuso. – Marcel

+0

Quizás una combinación de serialización binaria y análisis de reflexión profunda (como en mi idea) en caso de discrepancia en la comparación binaria lo resolverá. – Migol

1

Usaría el truco para hacer una comparación XML. O puede usar el reflejo para atravesar automáticamente las propiedades del objeto (pero esto atravesará TODAS ellas, también algunas que no podría desear).

+0

Desafortunadamente, el truco es manipular un archivo generado (generado por el marco de entidad) – Marcel

+0

¿No son parciales las clases generadas por el marco de entidad? ¿No puedes aplicar el "truco" en otro archivo extendiendo las clases parciales según sea necesario? Si usa VS2010, también incluye la plantilla ADO.NET EntityObject Generator. Luego, puede modificar la plantilla de Objetos de la entidad para que coincida con sus requisitos. – FuleSnabel

1

Haría que cada tipo personalizado heredara IComparable, y proporcionase métodos de igualdad, que compararan cada tipo personalizado, además de hacer que la clase principal ICompareble, simplemente puede comparar los 2 objetos (si los tiene en la memoria cuando se ejecutan) pruebas unitarias) Si no, sugeriría serializar o definir las constantes que espera que tenga el objeto refactorizado.

+0

Bueno, es una buena solución también, ya que agrega algunas funcionalidades a las clases al costo de escribir código y posibles fugas (si algún objeto no proporciona IComparable, entonces NO será confiable). – Migol