2010-02-05 13 views
13

Tengo dos objetos en mi prueba de unidad, el objeto real y esperado. Todas las propiedades en el método objeto son exactamente el mismo y si funciono el siguiente ensayo:Comparación de objetos en pruebas unitarias

Assert.AreEqual(expectedObject.Property1, actualObject.Property1); 

el resultado pases como se esperaba. Sin embargo, cuando trato de ejecutar la siguiente prueba falla:

Assert.AreEqual (expectedObject, actualObject); 

¿Qué me falta? ¿No se pueden comparar dos objetos y debo verificar cada propiedad?

+2

He aquí una pregunta similar para NUnit que será útil: http://stackoverflow.com/questions/318210/compare-equality-between-two-objects-in-nunit –

+0

para realizar realmente la trabajo que le gustaría. Escribí una clase de utilidad que compara las propiedades de los dos objetos mediante el uso de la reflexión. Por el momento no tengo el código a mano, pero no es difícil implementar tal funcionalidad. – Juri

+0

Si encuentras ese código Juri, me encantaría ver lo que has hecho. –

Respuesta

15

Debe sobrescribir Equals para su objeto. Assert utiliza Object.Equals. Por defecto, Object.Equals en objetos de tipo de referencia realiza una comparación de referencia. Es decir, dos instancias de un tipo de referencia son iguales si y solo si se refieren al mismo objeto. Desea anular esto para que, en lugar de realizar una comparación de referencia, se realice una comparación de valores. Aquí hay un muy buen MSDN article sobre el tema. Tenga en cuenta que también debe sobrescribir GetHashCode. Ver MSDN para el guidelines. Aquí está un ejemplo sencillo:

Antes:

class Test { 
    public int Value { get; set; } 
} 

Test first = new Test { Value = 17 }; 
Test second = new Test { Value = 17 }; 
Console.WriteLine(first.Equals(second)); // false 

Después:

class Test { 
    public int Value { get; set; } 
    public override bool Equals(object obj) { 
     Test other = obj as Test; 
     if(other == null) { 
      return false; 
     } 
     return this.Value == other.Value; 
    } 
    public override int GetHashCode() { 
     return this.Value.GetHashCode(); 
    } 
} 

Test first = new Test { Value = 17 }; 
Test second = new Test { Value = 17 }; 
Console.WriteLine(first.Equals(second)); // true 
+0

¿Puedes dar más detalles sobre esto? –

+2

Tenga cuidado con la contaminación de la igualdad. Ignorar Iguales puede no ser lo correcto. Consulte aquí para obtener más información: http://stackoverflow.com/questions/2046121/how-to-compare-two-object-in-unit-test-how-to-compare-two-collection-in-unit-tes/ 2047576 # 2047576 –

4

La segunda sentencia assert realidad compara las referencias de los objetos, no el contenido. Dado que los parámetros del método AreEqual son de tipo objetos, no hay mucha información sobre cómo el marco de prueba de la unidad debe compararlos.

EDIT: marque esta pregunta: Compare equality between two objects in NUnit

+1

ah ... demasiado tarde :) Estaba escribiendo lo mismo :) (+1) – Juri

+0

Ahhhh, buena idea. No vi la pregunta nUnit cuando publiqué. –

1

No se podía utilizar el signo '=' a menos que haya una sobrecarga a su objeto. En su clase de objeto que hay que hacer algo como:


public override bool Equals(object obj) 
{ 
    if(obj == null) 
     return false; 
    return (this.Property1 == obj.Property1 && 
      this.Property2 == obj.Property2); 
} 

Si no lo hace, entonces usted está simplemente comparando las referencias a objetos.

1

Esto es cierto. Que los dos objetos sean iguales o no depende completamente de la implementación de su método Equals. En algún momento con el método Equal, también es bueno anular la implementación de GetHashCode. Si no se reemplaza, se considerará la implementación virtual predeterminada (de la clase Object) junto con la evaluación del método Equal. Para que el objeto se considere igual, su código hash debe ser el mismo.

Sin embargo, para la prueba unitaria, sugeriría que no confíe mucho en la implementación del método Equal. Cualquiera sea la propiedad que desee determinar, compare las propiedades del objeto usted mismo porque, una vez más, el método Equal podría ser la implementación personalizada, por lo que es posible que contenga errores al final del día. Así que es mejor confiar en el método Equal de la clase definida por el sistema para las pruebas unitarias.

0

Deepak: Eso significa que al final del día no compararé los objetos. Compare el valor de las propiedades de los objetos. Correcto ... Este método de anulación igual es solo para Objeto particular ... Esto no es una forma correcta de limitación ...

Aquí es un buen enlace ...Antes Prepare unittest hacer su propia clase para Pruebas Ayuda

http://manfred-ramoser.blogspot.com/2007/11/c-unit-testing-helper.html

0

https://github.com/kbilsted/StatePrinter se ha escrito específicamente para volcar gráficos de objetos de representación de cadena con el objetivo de escribir las pruebas unitarias fáciles.

  • Viene con los métodos de Assert que producen fácilmente una cadena escapada fácil de copiar y pegar en la prueba para corregirla.
  • Permite unittest a ser automáticamente re-escrito
  • Se integra con todas las pruebas unitarias marcos
  • A diferencia de la serialización JSON, las referencias circulares son compatibles
  • puede filtrar con facilidad, por lo que sólo partes de los tipos se vierten

Dada

class A 
{ 
    public DateTime X; 
    public DateTime Y { get; set; } 
    public string Name; 
} 

Se puede de manera segura el tipo y el uso de auto-completado de Visual Studio incluye o excluye campos.

var printer = new Stateprinter(); 
    printer.Configuration.Projectionharvester().Exclude<A>(x => x.X, x => x.Y); 

    var sut = new A { X = DateTime.Now, Name = "Charly" }; 

    var expected = @"new A(){ Name = ""Charly""}"; 
    printer.Assert.PrintIsSame(expected, sut); 
0

eso es típico de equivalencia problema y se ve como respuesta aceptada no es una buena idea. Trataré de explicar por qué.

Imagínese lo siguiente: tiene que escribir la prueba de integración en su servidor para asegurarse de que almacena su objeto de dominio de forma correcta. Usted tiene un código:

[TestMethod] 
    [Description(@"Sequentially perform operations 
       1. Save new item in DB 
       2. Get same Item from DB 
       Ensure that saved and get Items are equivalent")] 
    public void Repository_Create_Test() 
    { 
     var initialItem = GetTestItem(); 
     //create item and check it is created correct 
     initialItem.ID = repository.Create(initialItem, userID, ownerID); 
     Item resultItem = repository.GetById(initialItem.ID, ownerID); 
     resultItem.Should().NotBeNull(); 
     Assert.AreEqual(initialItem, resultItem); 
    } 

Por lo tanto, es necesario verificar que el objeto leído de almacenamiento es absoluta equivalente del objeto que hemos enviamos al almacenamiento. Sobrescribir Equals es una primera adivinanza fácil aquí. Para este caso, necesitamos configurar Equals para comparar todos los campos de objetos. Pero desde la perspectiva de DDD eso es simplemente incorrecto. Las entidades de dominio se distinguen por una clave inmutable (o clave principal) y no por todos los campos mutables. Entonces, si estamos modelando el dominio de recursos humanos y el hipotético 'Mister X' tiene un nuevo número de teléfono, él sigue siendo el mismísimo 'Mister X'.

Dicho todo esto, actualmente uso FluentAssertions Framework que tiene una facilidad bastante poderosa para la comprobación de equivalencia. De esta manera:

resultItem.ShouldBeEquivalentTo(initialItem);