2011-06-13 14 views
10

Tengo una unidad de prueba para un método que obtiene un objeto de una colección. Esto sigue fallando y no puedo ver por qué, así que he creado una prueba muy simple a continuación para crear 2 objetos del proveedor y probar que son iguales para ver si puedo detectar el problema en mi prueba de mi código. Pero esta prueba nuevamente está fallando. ¿Alguien puede ver o explicar por qué?Unidad Prueba Assert.AreEqual failed

[TestMethod()] 
    public void GetSupplierTest2() 
    { 
     Supplier expected = new Supplier(); 
     expected.SupplierID = 32532; 
     expected.SupplierName = "Test 1" 

     Supplier actual = new Supplier(); 
     actual.SupplierID = 32532; 
     actual.SupplierName = "Test 1" 

     Assert.AreEqual(expected, actual); 
    } 

Pero si pongo a prueba las propiedades individuales de los objetos pasa la prueba ...

[TestMethod()] 
    public void GetSupplierTest2() 
    { 
     Supplier expected = new Supplier(); 
     expected.SupplierID = 32532; 
     expected.SupplierName = "Test 1" 

    Supplier actual = new Supplier(); 
     actual.SupplierID = 32532; 
     actual.SupplierName = "Test 1" 

     Assert.AreEqual(expected.SupplierID , actual.SupplierID); 
     Assert.AreEqual(expected.SupplierName , actual.SupplierName); 
    } 

Respuesta

4

Si desea comparar dos instancias diferentes de Proveedor y desea que se consideren iguales cuando ciertas propiedades tienen el mismo valor, debe anular el método Equals en Supplier y comparar esas propiedades en el método.

Puede leer más sobre el método Equals aquí: http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx

aplicación Ejemplo:

public override bool Equals(object obj) 
{ 
    if (obj is Supplier) 
    { 
     Supplier other = (Supplier) obj; 
     return Equals(other.SupplierID, this.SupplierID) && Equals(other.SupplierName, this.SupplierName); 
    } 
    return false; 
} 

Tenga en cuenta que también obtendrá una advertencia del compilador que hay que poner en práctica GetHashCode así, que podrían sea ​​tan simple como esto:

public override int GetHashCode() 
{ 
    return SupplierID; 
} 
+0

¿Puede ampliar el método Equals por favor? – suggy1982

2

Se trata de comparar 2 instancias diferentes del tipo de proveedor, por eso aserción falle.

Si desea Proveedor son iguales dicen (por su Id) puede anular Igual método, aquí muy por encima de ejemplo simpled,: D.

public class Supplier 
{ 
    private int id; 
    private string name; 

    public int Id 
    { 
     get { return id; } 
    } 

    public string Name 
    { 
     get { return name; } 
    } 

    public bool Equals(Supplier other) 
    { 
     if(other == null) return false; 
     return other.id == id; 
    } 

    public override bool Equals(object obj) 
    { 
     if(obj == null) return false; 
     if (obj.GetType() != typeof (Supplier)) return false; 
     return Equals((Supplier) obj); 
    } 

    public override int GetHashCode() 
    { 
     return id; 
    } 
} 
+0

Gracias, entonces ¿cómo probarías la unidad en un escenario como este? ¿Es el enfoque correcto simplemente comparar los valores de cada propiedad o hay un método para comparar un objeto con un objeto? – suggy1982

+0

puede anular la función Igual –

+0

¿Puede ampliar esto un poco por favor? – suggy1982

1

Al probar las propiedades individuales, se comparan los valores de cadena/número entero. Son iguales, y así pasan las pruebas.

Cuando se prueban los objetos padre, se comparan solo las dos estructuras de contenedor de tipo Proveedor - y aunque pueden tener valores de propiedades iguales, no son iguales: dado que se crean dos objetos separados, no residen en el misma dirección en la memoria.

+0

Gracias, ¿cómo probarías un escenario como este? ¿Hay algún método para comparar un objeto con un objeto? – suggy1982

+0

Como han sugerido los otros dos pósters, puede anular el método Equals del tipo Proveedor y hacer que compare los valores de las propiedades individuales. Consulte este tutorial, por ejemplo: http://msdn.microsoft.com/en-us/library/336aedhh(v=vs.71).aspx – weltraumpirat

22

Como todas las demás respuestas dicen que el problema es que está tratando de comparar instancias de Supplier [probablemente] sin anular el método Equals. Pero no creo que deba anular Equals con fines de prueba ya que puede afectar el código de producción o puede necesitar otra lógica Equals en el código de producción.

En su lugar, debe afirmar cada miembro uno por uno como lo hace en la primera muestra (si no tiene muchos lugares donde desea comparar todo el objeto) o encapsular esta lógica de comparación en alguna clase y usar esto clase:

static class SupplierAllFieldsComparer 
{ 
    public static void AssertAreEqual(Supplier expected, Supplier actual) 
    { 
     Assert.AreEqual(expected.SupplierID , actual.SupplierID); 
     Assert.AreEqual(expected.SupplierName , actual.SupplierName);    
    } 
} 

// código de ensayo:

SupplierAllFieldsComparer.AssertAreEqual(expected, actual); 
+2

Estoy totalmente de acuerdo. Sugiero leer esto: http://stackoverflow.com/questions/1180044/should-one-override-equals-method-for-asserting-the-object-equality-in-a-unit-tes – steenhulthin

3

la implementación predeterminada de Object.Equals para los tipos de referencia es "Igualdad de referencia" (es decir, las clases.): son los dos objetos en realidad la misma instancia. No compara los valores de los campos.

Cualquiera (como otros han demostrado) anula Equals para dar "Value Equality". En este caso, también debe anular GetHashCode (para que los contenedores funcionen), y debe anular operator ==.

O bien, acepte que la mayoría de las entidades deben tener igualdad de referencia (dos proveedores con el mismo nombre no son siempre la misma organización) y realmente usar las propiedades directamente.

0
//Given the following structure and an instance value, targetObj... 

class BaseType 
{ 
    private FeatureType Feature_1; 
} 

class TargetType : BaseType 
{ 
    ... 
} 

TargetType targetObj = new TargetType(); 

//...a private feature in a specific base class can be accessed as follows 

PrivateType typeCast = new PrivateType(typeof(BaseType)); 

PrivateObject privateObj = new PrivateObject(targetObj, typeCast); 

//...and values can be retrieved and set as follows.... 

privateObj.SetField("Feature_1", (FeatureType) newValue); 

FeatureType result = (FeatureType) privateObj.GetField("Feature_1"); 

/* Con respecto a la controversia en torno a acceder a los campos privados en las pruebas de unidad, creo que no debe utilizarse a menos (es decir, problemas de tiempo y de gastos de gestión) absolutamente necesario. */