2009-01-20 14 views
5

recientemente me topé con un comportamiento aparentemente extraño que Google no pudo explicar por completo.C# UnitTest - Assert.AreEqual() no llama a Igualdad si el argumento es nulo


using Microsoft.VisualStudio.TestTools.UnitTesting; 

class TestClass 
{ 
    public override bool Equals(object obj) 
    { 
     return true; 
    } 
} 

[TestMethod] 
public void TestMethod1() 
{ 
    TestClass t = new TestClass(); 
    Assert.AreEqual (t, null); // fails 
    Assert.IsTrue (t.Equals (null)); // passes 
} 

Esperaré que esta prueba tenga éxito. Sin embargo, en Visual Studio 2008/.NET 3.5 falla. ¿Tiene la intención de ser así o es un error?

+1

Dado que el valor esperado en NUnit es siempre el primero, está utilizando AreEqual() hacia atrás desde la convención. No puedo decir de los documentos si se compara t contra nulo, o nulo contra t, por lo que no llamaría confiable a una prueba que se base en esa distinción. – Ken

Respuesta

15

Su TestClass infringe el contrato de Object.Equals. Assert.AreEqual se basa en ese contrato, bastante razonablemente.

El estado docs (en la lista de requisitos):

  • x.equals (una referencia nula (Nothing en Visual Basic)) devuelve falso.
+0

Entonces, ¿por qué pasa la última afirmación? ¿No debería t.Equals (null) devolver false y hense no ser Assert.Istrue? –

+0

@borisCallens: La afirmación pasa * porque * la implementación está violando el contrato. 't.Equals (null)' * should * devuelve false, pero se puede ver en la implementación que * en realidad * es verdadero, por lo que la aseveración rota pasa. –

+0

Ah, suponía que el marco omitiría la implementación real en caso de nulo y simplemente devuelve falso. –

5

Al probar nulos, no use Assert.AreEqual.

Tienes que usar Assert.IsNull() para eso.

1

La primera prueba falla. Pruebe si "t" es nulo, que no es, porque usted inicializó el t con un nuevo objeto TestClass.

La segunda prueba, pasa, porque t.Equals siempre devuelve verdadero.

Si falla una prueba, todo el TestMethod1 se marca como fallido.

1

No, es correcto: ha inicializado t a un nuevo objeto TestClass, que no es nulo, por lo que la afirmación falla.

0

Si entiendo bien, en realidad se pretende que AreEqual(anythingButNull, null) siempre devuelva falso?

(edit) La razón por la que me pregunté es porque la prueba de nulo, como lo exige el contrato de Equals, no se llama al realizar una prueba unitaria de la clase. Entonces, como AreEqual depende del contrato, no verifica si mi clase también cumple con el contrato. Así que supongo que tengo que usar la solución de Assert.IsFalse(blah.Equals(null)).

+0

Sí, exactamente especificado en los documentos para Object.Equals. –

+0

Sí, porque, simplemente dicho, (! Null == null) tiene que devolver falso. – Xn0vv3r

Cuestiones relacionadas