So vergleichen Sie Listen in Unit-Tests

180

Wie kann dieser Test fehlschlagen?

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

Antworten:

370

Um Aussagen über Sammlungen zu machen, sollten Sie Folgendes verwenden CollectionAssert:

CollectionAssert.AreEqual(expected, actual);

List<T>wird nicht überschrieben Equals. Wenn also Assert.AreEqualnur aufgerufen wird Equals, wird die Referenzgleichheit verwendet.

Jon Skeet
quelle
6
Ich wünschte, dies würde detailliertere Nachrichten geben, wenn es fehlschlug. "Unterschiedliche Anzahl von Elementen" und "Element bei Index 0 stimmen nicht überein" sind leicht nutzlos. Was sind sie dann?!
Colonel Panic
32
Wenn Sie sich nicht für die ArtikelreihenfolgeCollectionAssert.AreEquivalent
interessieren
2
Beachten Sie, CollectionAssert.AreEqualdass spürbar langsamer sein kann alsAssert.IsTrue...SequenceEqual
Mark Sowul
1
@ MarkSowul: Aber es kommt mit einer viel besseren Fehlerdiagnose, oder?
Jon Skeet
2
@ MarkSowul: Hmm ... hört sich so an, als wäre es wert, als Fehler gemeldet zu werden. Kein Grund, warum es so schlimm sein sollte.
Jon Skeet
34

Ich denke, das wird helfen

Assert.IsTrue(expected.SequenceEqual(actual));
Shyju
quelle
4
Das war auch mein Rückfall, aber ich hoffe, dass CollectionAssert hilfreichere Fehlermeldungen liefert.
Jon Skeet
4
Leider nicht wirklich: "CollectionAssert.AreEqual fehlgeschlagen. (Element bei Index 0 stimmt nicht überein.)" (Was sind die Elemente?)
Namey
17

Wenn Sie überprüfen möchten, ob jede dieselbe Auflistung von Werten enthält, sollten Sie Folgendes verwenden:

CollectionAssert.AreEquivalent(expected, actual);

Bearbeiten:

"Zwei Sammlungen sind äquivalent, wenn sie dieselben Elemente in derselben Menge, aber in beliebiger Reihenfolge haben. Elemente sind gleich, wenn ihre Werte gleich sind, nicht wenn sie sich auf dasselbe Objekt beziehen." - https://msdn.microsoft.com/en-us/library/ms243779.aspx

topham101
quelle
14

Ich habe die anderen Antworten in diesem Thread ausprobiert und sie haben bei mir nicht funktioniert. Ich habe Sammlungen von Objekten verglichen, in deren Eigenschaften dieselben Werte gespeichert waren, die Objekte jedoch unterschiedlich waren.

Methodenaufruf:

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

Vergleichsmethode:

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
quelle
3
Netter Zusatz, oder Sie können auch die EqualsMethode überschreiben und das CollectionAssertwird funktionieren.
Ray Cheng
6

Dieser Test vergleicht eine Datumseingabe und prüft, ob es sich um ein Schaltjahr handelt. Wenn ja, werden 20 Schaltjahre vom eingegebenen Datum ausgegeben. Wenn nicht, werden die NÄCHSTEN 20 Schaltjahre ausgegeben, myTest.Testing bezieht sich auf die myTest-Instanz, die wiederum die Werte aufruft aus einer Liste namens Testing, die die erforderlichen berechneten Werte enthält. Teil einer Übung, die ich machen musste.

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

//Handlung

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

//Behaupten

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
quelle
0

Fließende Behauptungen führen tiefe Vergleiche von Arrays durch actualArray.Should().BeEquivalentTo(expectedArray)

Ram Pratap
quelle