Estoy tratando de afirmar que un objeto es "igual" a otro objeto.
Los objetos son solo instancias de una clase con un conjunto de propiedades públicas. ¿Hay una manera fácil de hacer que NUnit afirme la igualdad en función de las propiedades?
Esta es mi solución actual, pero creo que puede haber algo mejor:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
Lo que voy a buscar estaría en el mismo espíritu que la CollectionEquivalentConstraint en la que NUnit verifica que el contenido de dos colecciones sea idéntico.
fuente
IEnumerable
, se comparará como una colección, independientemente de las implementacionesEquals
anuladas porque NUnit le daIEnumerable
mayor prioridad. Vea losNUnitEqualityComparer.AreEqual
métodos para más detalles. Puede anular el comparador utilizando uno de losUsing()
métodos de restricción de igualdad . Incluso entonces, no es suficiente implementar el no genéricoIEqualityComparer
debido al adaptador que utiliza NUnit.GetHashCode()
en tipos mutables se comportará mal si alguna vez usa ese objeto como clave. En mi humilde opinión, anulandoEquals()
,GetHashCode()
y haciendo que el objeto inmutable sólo para probar que no tiene sentido.Si no puede anular Equals por algún motivo, puede crear un método auxiliar que recorra en iteración las propiedades públicas mediante reflexión y afirme cada propiedad. Algo como esto:
fuente
No anule Equals solo con fines de prueba. Es tedioso y afecta la lógica del dominio. En lugar,
Use JSON para comparar los datos del objeto.
No hay lógica adicional en sus objetos. No hay tareas adicionales para probar.
Solo usa este método simple:
Parece funcionar muy bien. La información de resultados del corredor de prueba mostrará la comparación de cadenas JSON (el gráfico de objetos) incluida para que pueda ver directamente lo que está mal.
También tenga en cuenta! Si tiene objetos complejos más grandes y solo desea comparar partes de ellos, puede ( usar LINQ para datos de secuencia ) crear objetos anónimos para usar con el método anterior.
fuente
Pruebe la biblioteca FluentAssertions:
http://www.fluentassertions.com/
También se puede instalar usando NuGet.
fuente
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Prefiero no anular Equals solo para habilitar las pruebas. No olvide que si anula Equals, debería anular también GetHashCode o puede obtener resultados inesperados si utiliza sus objetos en un diccionario, por ejemplo.
Me gusta el enfoque de reflexión anterior, ya que atiende la adición de propiedades en el futuro.
Para una solución rápida y simple, sin embargo, a menudo es más fácil crear un método auxiliar que pruebe si los objetos son iguales o implementar IEqualityComparer en una clase que mantenga privada para sus pruebas. Cuando utilice la solución IEqualityComparer, no necesita preocuparse por la implementación de GetHashCode. Por ejemplo:
fuente
He intentado varios enfoques mencionados aquí. La mayoría implica serializar sus objetos y hacer una comparación de cadenas. Si bien es muy fácil y, en general, muy efectivo, descubrí que es un poco corto cuando tienes un error y se informa algo como esto:
Averiguar dónde están las diferencias es un dolor, por decir lo menos.
Con las comparaciones de gráficos de objetos de FluentAssertions (es decir
a.ShouldBeEquivalentTo(b)
), obtienes esto:Eso es mucho mejor. Obtenga FluentAssertions ahora, se alegrará más tarde (y si votó a favor de esto, también votó a favor la respuesta de dkl donde se sugirió por primera vez FluentAssertions).
fuente
Estoy de acuerdo con ChrisYoxall: implementar Equals en su código principal solo para fines de prueba no es bueno.
Si está implementando Equals porque alguna lógica de la aplicación lo requiere, entonces está bien, pero mantenga el código puro de solo pruebas fuera del desorden (también la semántica de verificar lo mismo para las pruebas puede ser diferente de lo que requiere su aplicación).
En resumen, mantenga el código de solo prueba fuera de su clase.
La comparación simple y superficial de las propiedades mediante la reflexión debería ser suficiente para la mayoría de las clases, aunque es posible que deba repetir si sus objetos tienen propiedades complejas. Si sigue las referencias, tenga cuidado con las referencias circulares o similares.
Astuto
fuente
Las restricciones de propiedad , agregadas en NUnit 2.4.2, permiten una solución que es más legible que la original del OP, y produce mensajes de falla mucho mejores. No es de ninguna manera genérico, pero si no necesita hacerlo durante demasiadas clases, es una solución muy adecuada.
No es tan general como la implementación,
Equals
pero da un mensaje de falla mucho mejor quefuente
La solución JSON de Max Wikstrom (arriba) tiene más sentido para mí, es corta, limpia y, lo más importante, funciona. Personalmente, aunque preferiría implementar la conversión JSON como un método separado y colocar la afirmación nuevamente dentro de la prueba de la unidad de esta manera ...
MÉTODO DE AYUDA:
PRUEBA DE UNIDAD :
FYI: es posible que deba agregar una referencia a System.Web.Extensions en su solución.
fuente
Este es un hilo bastante antiguo, pero me preguntaba si hay una razón por la que no se propone una respuesta
NUnit.Framework.Is.EqualTo
yNUnit.Framework.Is.NotEqualTo
.Como:
y
fuente
Otra opción es escribir una restricción personalizada implementando la
Constraint
clase abstracta NUnit . Con una clase auxiliar para proporcionar un poco de azúcar sintáctica, el código de prueba resultante es agradablemente breve y legible, por ejemploPara un ejemplo extremo, considere la clase que tiene miembros de 'solo lectura', no es
IEquatable
, y no podría cambiar la clase bajo prueba incluso si quisiera:El contrato para la
Constraint
clase requiere que uno anuleMatches
yWriteDescriptionTo
(en el caso de un desajuste, una narrativa para el valor esperado) pero también anularWriteActualValueTo
(narrativa para el valor real) tiene sentido:Además de la clase auxiliar:
Ejemplo de uso:
fuente
Me basaría en la respuesta de @Juanma. Sin embargo, creo que esto no debería implementarse con afirmaciones de prueba de unidad. Esta es una utilidad que bien podría ser utilizada en algunas circunstancias por código que no sea de prueba.
Escribí un artículo sobre el tema http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Mi propuesta es la siguiente:
Usando esto con NUnit
produce el siguiente mensaje en caso de falta de coincidencia.
fuente
https://github.com/kbilsted/StatePrinter se ha escrito específicamente para volcar gráficos de objetos en la representación de cadenas con el objetivo de escribir pruebas unitarias fáciles.
Dado
Puede escribir de forma segura y utilizando la finalización automática de Visual Studio incluir o excluir campos.
fuente
Simplemente instale ExpectedObjects de Nuget, puede comparar fácilmente el valor de propiedad de dos objetos, el valor de cada objeto de colección, el valor de dos objetos compuestos y el valor de propiedad de comparación parcial por tipo anónimo.
Tengo algunos ejemplos en github: https://github.com/hatelove/CompareObjectEquals
Aquí hay algunos ejemplos que contienen escenarios de comparación de objetos:
Referencia:
fuente
Echa un vistazo al siguiente enlace. Es una solución del proyecto de código y también la he usado. Funciona bien para comparar los objetos.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
fuente
Terminé escribiendo una fábrica de expresiones simples:
y solo úsalo:
Es muy útil ya que tengo que comparar la colección de tales objetos. Y puedes usar esta comparación en otro lugar :)
Aquí está lo esencial con un ejemplo: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
fuente
Deserialice ambas clases y haga una comparación de cadenas.
EDITAR: funciona perfectamente, esta es la salida que obtengo de NUnit;
EDITAR DOS: Los dos objetos pueden ser idénticos, pero el orden en el que se serializan las propiedades no es el mismo. Por lo tanto, el XML es diferente. DOH!
EDITAR TRES: Esto funciona. Lo estoy usando en mis pruebas. Pero debe agregar elementos a las propiedades de la colección en el orden en que el código bajo prueba los agrega.
fuente
Sé que esta es una pregunta muy antigua, pero NUnit todavía no tiene soporte nativo para esto. Sin embargo, si le gustan las pruebas de estilo BDD (ala Jasmine), se sorprenderá gratamente con NExpect ( https://github.com/fluffynuts/NExpect , obténgalo de NuGet), que tiene pruebas de igualdad profunda al horno allí mismo .
(descargo de responsabilidad: soy el autor de NExpect)
fuente
Stringify y compara dos cadenas
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
fuente
fuente