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
}
Ray Cheng
la source

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.

Jon Skeet
la source
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));
Shyju
la source
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

topham101
la source
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);
        }
    }
Declan
la source
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);
        }
arriverThereSlowly
la source
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
karthik kasubha
la source
0

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

Ram Pratap
la source