Comment comparer des listes dans les tests unitaires


183

Comment ce test peut-il échouer?

[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
}

Réponses:


376

Pour faire des affirmations sur les collections, vous devez utiliser CollectionAssert:

CollectionAssert.AreEqual(expected, actual);

List<T>ne remplace pas Equals, donc s'il s'agit Assert.AreEqualsimplement d'appels Equals, il finira par utiliser l'égalité de référence.


6
Je souhaite que cela donne des messages plus détaillés en cas d'échec. "Différents nombres d'éléments" et "L'élément à l'index 0 ne correspondent pas" sont légèrement inutiles. Que sont-ils alors?!
Colonel Panic

34
Si vous ne vous souciez pas de l'ordre des articles: {A, B, C} == {C, B, A}, utilisez à la CollectionAssert.AreEquivalentplace msdn.microsoft.com/en-us/library/ms243779.aspx
user2023861

2
Notez que CollectionAssert.AreEqualpeut être nettement plus lent queAssert.IsTrue...SequenceEqual
Mark Sowul

1
@MarkSowul: Mais il est livré avec de bien meilleurs diagnostics de panne, non?
Jon Skeet

2
@MarkSowul: Hmm ... on dirait que ça vaut la peine d'être signalé comme un bug alors. Aucune raison que ça ne soit si grave.
Jon Skeet

34

Je suppose que cela aidera

Assert.IsTrue(expected.SequenceEqual(actual));

4
C'était aussi ma solution de rechange, mais j'espère que CollectionAssert fournirait des messages d'échec plus utiles.
Jon Skeet

4
Malheureusement, ce n'est pas vraiment le cas: "CollectionAssert.AreEqual a échoué. (L'élément à l'index 0 ne correspond pas.)" (Quels sont les éléments?)
namey

17

Si vous voulez vérifier que chacun contient la même collection de valeurs, vous devez utiliser:

CollectionAssert.AreEquivalent(expected, actual);

Éditer:

"Deux collections sont équivalentes si elles ont les mêmes éléments dans la même quantité, mais dans n'importe quel ordre. Les éléments sont égaux si leurs valeurs sont égales, pas s'ils font référence au même objet." - https://msdn.microsoft.com/en-us/library/ms243779.aspx


15

J'ai essayé les autres réponses dans ce fil, et elles ne fonctionnaient pas pour moi et je comparais des collections d'objets qui avaient les mêmes valeurs stockées dans leurs propriétés, mais les objets étaient différents.

Appel de méthode:

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

Méthode de comparaison:

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);
        }
    }

3
Bel ajout, ou vous pouvez également remplacer la Equalsméthode et la CollectionAssertvolonté fonctionnera.
Ray Cheng

6

ce test compare une entrée de date, vérifie si c'est une année bissextile, le cas échéant, génère 20 années bissextiles à partir de la date saisie, sinon, affiche les 20 prochaines années bissextiles, myTest. à partir d'une liste appelée Testing contenant les valeurs calculées requises. partie d'un exercice que je devais faire.

[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);
        }

0
List<AdminUser> adminDetailsExpected = new List<AdminUser>()
{
new AdminUser  {firstName = "test1" , lastName = "test1" , userId = 
"001test1"  },
new AdminUser {firstName = "test2" , lastName = "test2" , userId = 
"002test2"   }
};

//Acte

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

//Affirmer

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

0

Les assertions fluides effectuent des comparaisons approfondies de tableaux actualArray.Should().BeEquivalentTo(expectedArray)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.