it-swarm.dev

¿Cuál es la diferencia entre Assert.AreNotEqual y Assert.AreNotSame?

En C #, ¿cuál es la diferencia entre

Assert.AreNotEqual

y

Assert.AreNotSame
60
Dan Esparza

Casi todas las respuestas dadas aquí son correctas, pero probablemente valga la pena dar un ejemplo:

public static string GetSecondWord(string text)
{
    // Yes, an appalling implementation...
    return text.Split(' ')[1];
}

string expected = "world";
string actual = GetSecondWord("hello world");

// Good: the two strings should be *equal* as they have the same contents
Assert.AreEqual(expected, actual);

// Bad: the two string *references* won't be the same
Assert.AreSame(expected, actual);

AreNotEqual y AreNotSame son solo inversiones de AreEqual y AreSame por supuesto.

EDITAR: una refutación a respuesta actualmente aceptada ...

Si usa Assert.AreSame con tipos de valor, se encuadran. En otras palabras, es equivalente a hacer:

int firstNumber = 1;
int secondNumber = 1;
object boxedFirstNumber = firstNumber;
object boxedSecondNumber = secondNumber;

// There are overloads for AreEqual for various value types
// (assuming NUnit here)
Assert.AreEqual(firstNumber, secondNumber);

// ... but not for AreSame, as it's not intended for use with value types
Assert.AreSame(boxedFirstNumber, boxedSecondNumber);

Ni firstNumber ni secondNumber tiene un valor de objeto, porque int es un tipo de valor. La razón por la que la llamada AreSame fallará es porque en .NET, al colocar un valor en un cuadro se crea un nuevo cuadro cada vez. (En Java a veces no lo hace, esto me ha sorprendido antes).

Básicamente, debe nunca usar AreSame al comparar tipos de valores. Cuando esté comparando tipos de referencia , use AreSame si desea verificar referencias idénticas; use AreEqual para verificar la equivalencia en Equals. EDITAR: Tenga en cuenta que hay situaciones en las que NUnit no solo usa Equals directamente; tiene soporte incorporado para colecciones, donde los elementos en las colecciones se prueban para la igualdad.

El reclamo en la respuesta que:

Usando el ejemplo anterior cambiando el int a string, AreSame y AreEqual devolverán el mismo valor.

depende completamente de cómo se inicializan las variables. Si usan literales de cadena, entonces, la internación se encargará de eso. Sin embargo, si usa:

string firstString = 1.ToString();
string secondString = 1.ToString();

entonces AreSame y AreEqual seguramente no devolverán el mismo valor.

Como para:

La regla general es usar AreEqual en los tipos de valor y AreSame en los tipos de referencia.

Casi nunca quiero verificar la identidad de referencia. Raramente me es útil. Quiero verificar la equivalencia que es lo que comprueba AreEqual. (No estoy diciendo que AreSame no debería estar allí; es un método útil, solo que mucho más raramente que AreEqual.)

81
Jon Skeet

Dos cosas pueden ser iguales, pero diferentes objetos. AreNotEqual comprueba los objetos valores mediante la prueba de igualdad, mientras que AreNotSame comprueba que no son el mismo objeto exacto.

Es obvio por qué querríamos probar que las cosas no son iguales (nos preocupamos por los valores que se prueban); ¿Qué pasa con AreNotSame? La utilidad de esto en las pruebas se encuentra cuando ha pasado referencias y quiere asegurarse de que después de realizar la combinación aleatoria, dos referencias sigan siendo el mismo objeto.

En un caso del mundo real, utilizamos muchos objetos de almacenamiento en caché para mitigar los viajes de ida y vuelta a la base de datos. Después de que un objeto ha sido entregado al sistema de caché, nuestras pruebas unitarias aseguran que en algunos casos recuperemos el mismo objeto (el caché era válido) y en otros casos recuperamos un objeto nuevo (caché fue invalidado). Tenga en cuenta que AreNotEqual no sería suficiente en este caso. Si el objeto tenía una nueva marca de tiempo en la base de datos, pero data no era "lo suficientemente diferente" como para fallar una prueba de igualdad, AreNotEqual no notaría que actualizamos el objeto .

25
Godeke

AreNotSame hace una comparación de referencia, mientras que AreNotEqual hace una comparación de igualdad.

19
ermau

Assert.AreNotEqual afirma que dos valores no son iguales entre sí.

Assert.AreNotSame afirma que dos variables no apuntan al mismo objeto.

Ejemplo 1:

 int i = 1; 
 int j = i; 
 // Los valores son iguales: 
 Assert.AreEqual (i, j); 
 // Dos tipos de valores * no * representan el mismo objeto: 
 Assert.AreNotSame (i, j); 

Ejemplo 2

 string s = "A"; 
 string t = s; 
 // Los valores son iguales: 
 Assert.AreEqual (s, t); 
 // Los tipos de referencia * pueden * apuntar al mismo objeto: 
 Assert.AreSame (s, t); 
8
Ole Lynge

AreNotSame utiliza la igualdad de referencia (object.ReferenceEquals), es decir, son la misma instancia real de un objeto; AreNotEqual utiliza la igualdad conceptual (.Equals), es decir, son consideradas iguales.

7
Marc Gravell

¿No es así que AreNotEqual verifica el caso en el que dos objetos no son iguales en términos del método Equals (), mientras que AreNotSame verifica el caso en el que las dos referencias de objeto no son las mismas? Entonces, si x e y son dos objetos que son iguales en términos de Equals () pero se han asignado por separado, AreNotEqual () desencadenaría una afirmación errónea, pero el otro no.

3
Antti Huima