Jak porównać listy w testach jednostkowych

181

Jak ten test może się nie powieść?

[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
źródło

Odpowiedzi:

371

Aby twierdzić o kolekcjach, należy użyć CollectionAssert:

CollectionAssert.AreEqual(expected, actual);

List<T>nie zastępuje Equals, więc jeśli Assert.AreEqualtylko Equalswywoła, skończy się na równości referencji.

Jon Skeet
źródło
6
Chciałbym, żeby to dawało bardziej szczegółowe wiadomości, gdy zawiodło. „Różna liczba elementów” i „Element o indeksie 0 nie pasują” są nieco bezużyteczne. Czym oni są ?!
Pułkownik Panika
32
Jeśli nie zależy ci na zamówieniu przedmiotu: {A, B, C} == {C, B, A}, użyj CollectionAssert.AreEquivalentzamiast tego msdn.microsoft.com/en-us/library/ms243779.aspx
user2023861
2
Zauważ, że CollectionAssert.AreEqualmoże być zauważalnie wolniejszy niżAssert.IsTrue...SequenceEqual
Mark Sowul
1
@MarkSowul: Ale ma znacznie lepszą diagnostykę awarii, prawda?
Jon Skeet,
2
@MarkSowul: Hmm ... wydaje się, że warto zgłosić błąd. Bez powodu powinno być tak źle.
Jon Skeet,
34

Myślę, że to pomoże

Assert.IsTrue(expected.SequenceEqual(actual));
Shyju
źródło
4
To też było moje wycofanie, ale mam nadzieję, że CollectionAssert dostarczy bardziej pomocnych komunikatów o niepowodzeniach.
Jon Skeet,
4
Niestety tak naprawdę nie: „CollectionAssert.AreEqual nie powiodło się. (Element o indeksie 0 nie pasuje.)” (Jakie są elementy?)
imiennie
17

Jeśli chcesz sprawdzić, czy każda zawiera tę samą kolekcję wartości, powinieneś użyć:

CollectionAssert.AreEquivalent(expected, actual);

Edytować:

„Dwie kolekcje są równoważne, jeśli mają te same elementy w tej samej ilości, ale w dowolnej kolejności. Elementy są równe, jeśli ich wartości są równe, a nie jeśli odnoszą się do tego samego obiektu.” - https://msdn.microsoft.com/en-us/library/ms243779.aspx

topham101
źródło
14

Próbowałem innych odpowiedzi w tym wątku, ale one nie działały dla mnie i porównywałem kolekcje obiektów, które miały takie same wartości zapisane w swoich właściwościach, ale obiekty były różne.

Wywołanie metody:

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

Metoda porównań:

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
źródło
3
Fajny dodatek, możesz też przesłonić Equalsmetodę i CollectionAssertzadziała.
Ray Cheng
6

ten test porównuje wprowadzoną datę, sprawdza, czy jest to rok przestępny, jeśli tak, generuje 20 lat przestępnych od wprowadzonej daty, jeśli nie, wyświetla NASTĘPNE 20 lat przestępnych, myTest. Testowanie odnosi się do instancji myTest, która z kolei wywołuje wartości z listy o nazwie Testowanie zawierające wymagane obliczone wartości. część ćwiczenia, które musiałem wykonać.

[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
źródło
0
List<AdminUser> adminDetailsExpected = new List<AdminUser>()
{
new AdminUser  {firstName = "test1" , lastName = "test1" , userId = 
"001test1"  },
new AdminUser {firstName = "test2" , lastName = "test2" , userId = 
"002test2"   }
};

//Działać

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

//Zapewniać

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
źródło
0

Płynne twierdzenia dokonują głębokich porównań tablic actualArray.Should().BeEquivalentTo(expectedArray)

Ram Pratap
źródło