Cómo comparar listas en pruebas unitarias

181

¿Cómo puede fallar esta prueba?

[TestMethod]
public void Get_Code()
{
    var expected = new List<int>();
    expected.AddRange(new [] { 100, 400, 200, 900, 2300, 1900 });

    var actual = new List<int>();
    actual.AddRange(new [] { 100, 400, 200, 900, 2300, 1900 });

    Assert.AreEqual(expected, actual);
    // Assert.AreSame(expected, actual)       fails
    // Assert.IsTrue(expected.Equals(actual)) fails
}
Ray Cheng
fuente

Respuestas:

371

Para hacer afirmaciones sobre colecciones, debe usar CollectionAssert:

CollectionAssert.AreEqual(expected, actual);

List<T>no se anula Equals, por lo que si Assert.AreEqualsolo llama Equals, terminará usando la igualdad de referencia.

Jon Skeet
fuente
66
Desearía que esto diera mensajes más detallados cuando fallara. "Diferente número de elementos" y "Elemento en el índice 0 no coinciden" son ligeramente inútiles. ¿Qué son entonces?
Coronel Panic
32
Si no le importa el pedido de artículos: {A, B, C} == {C, B, A}, use CollectionAssert.AreEquivalenten su lugar msdn.microsoft.com/en-us/library/ms243779.aspx
user2023861
2
Tenga en cuenta que CollectionAssert.AreEqualpuede ser notablemente más lento queAssert.IsTrue...SequenceEqual
Mark Sowul
1
@ MarkSowul: Pero viene con diagnósticos de fallas mucho mejores, ¿verdad?
Jon Skeet
2
@ MarkSowul: Hmm ... parece que vale la pena informarlo como un error entonces. No hay razón para que sea tan malo.
Jon Skeet
34

Supongo que esto ayudará

Assert.IsTrue(expected.SequenceEqual(actual));
Shyju
fuente
44
Ese también fue mi inconveniente, pero espero que CollectionAssert proporcione mensajes de falla más útiles.
Jon Skeet
44
Lamentablemente, en realidad no: "CollectionAssert.AreEqual falló. (El elemento en el índice 0 no coincide)" (¿cuáles son los elementos?)
nombre
17

Si desea verificar que cada uno contiene la misma colección de valores, entonces debe usar:

CollectionAssert.AreEquivalent(expected, actual);

Editar:

"Dos colecciones son equivalentes si tienen los mismos elementos en la misma cantidad, pero en cualquier orden. Los elementos son iguales si sus valores son iguales, no si se refieren al mismo objeto". - https://msdn.microsoft.com/en-us/library/ms243779.aspx

topham101
fuente
14

Intenté las otras respuestas en este hilo, y no funcionaron para mí y estaba comparando colecciones de objetos que tenían los mismos valores almacenados en sus propiedades, pero los objetos eran diferentes.

Llamada de método:

CompareIEnumerable(to, emailDeserialized.ToIndividual,
            (x, y) => x.ToName == y.ToName && x.ToEmailAddress == y.ToEmailAddress);

Método para comparaciones:

private static void CompareIEnumerable<T>(IEnumerable<T> one, IEnumerable<T> two, Func<T, T, bool> comparisonFunction)
    {
        var oneArray = one as T[] ?? one.ToArray();
        var twoArray = two as T[] ?? two.ToArray();

        if (oneArray.Length != twoArray.Length)
        {
            Assert.Fail("Collections are not same length");
        }

        for (int i = 0; i < oneArray.Length; i++)
        {
            var isEqual = comparisonFunction(oneArray[i], twoArray[i]);
            Assert.IsTrue(isEqual);
        }
    }
Declan
fuente
3
Buena adición, o también puede anular el Equalsmétodo y CollectionAssertfuncionará.
Ray Cheng
6

esta prueba compara una entrada de fecha, verifica si es un año bisiesto, si es así, genera 20 años bisiestos a partir de la fecha ingresada, si no, emite los próximos 20 años bisiestos, myTest.Testing se refiere a la instancia myTest que a su vez llama a los valores de una Lista llamada Prueba que contiene los valores calculados requeridos. parte de un ejercicio que tuve que hacer.

[TestMethod]
        public void TestMethod1()
        {
            int testVal = 2012;
            TestClass myTest = new TestClass();
            var expected = new List<int>();
            expected.Add(2012);
            expected.Add(2016);
            expected.Add(2020);
            expected.Add(2024);
            expected.Add(2028);
            expected.Add(2032);
            expected.Add(2036);
            expected.Add(2040);
            expected.Add(2044);
            expected.Add(2048);
            expected.Add(2052);
            expected.Add(2056);
            expected.Add(2060);
            expected.Add(2064);
            expected.Add(2068);
            expected.Add(2072);
            expected.Add(2076);
            expected.Add(2080);
            expected.Add(2084);
            expected.Add(2088);
            var actual = myTest.Testing(2012);
            CollectionAssert.AreEqual(expected, actual);
        }
GettingThereSlowly
fuente
0
List<AdminUser> adminDetailsExpected = new List<AdminUser>()
{
new AdminUser  {firstName = "test1" , lastName = "test1" , userId = 
"001test1"  },
new AdminUser {firstName = "test2" , lastName = "test2" , userId = 
"002test2"   }
};

//Actuar

List<AdminUser> adminDetailsActual = RetrieveAdmin(); // your retrieve logic goes here

//Afirmar

Assert.AreEqual(adminDetailsExpected.Count, adminDetailsActual.Count);  //Test succeeds if the count matches else fails. This count can be used as a work around to test
karthik kasubha
fuente
0

Afirmaciones fluidas hace profundas comparaciones de matrices actualArray.Should().BeEquivalentTo(expectedArray)

Ram Pratap
fuente