xUnit: Zwei List <T> sind gleich?

108

Ich bin neu in TDD und xUnit und möchte meine Methode testen, die ungefähr so ​​aussieht:

List<T> DeleteElements<T>(this List<T> a, List<T> b);

Gibt es eine Assert-Methode, die ich verwenden kann? Ich denke so etwas wäre schön

List<int> values = new List<int>() { 1, 2, 3 };
List<int> expected = new List<int>() { 1 };
List<int> actual = values.DeleteElements(new List<int>() { 2, 3 });

Assert.Exact(expected, actual);

Gibt es so etwas?

Petar Petrov
quelle

Antworten:

134

xUnit.Net erkennt Sammlungen, sodass Sie dies nur tun müssen

Assert.Equal(expected, actual); // Order is important

Weitere verfügbare Sammlungszusicherungen finden Sie in CollectionAsserts.cs

Für NUnit- Bibliothekssammlungen gelten Vergleichsmethoden

CollectionAssert.AreEqual(IEnumerable, IEnumerable) // For sequences, order matters

und

CollectionAssert.AreEquivalent(IEnumerable, IEnumerable) // For sets, order doesn't matter

Weitere Details hier: CollectionAssert

MbUnit hat auch Sammlungszusicherungen ähnlich wie NUnit: Assert.Collections.cs

Konstantin Spirin
quelle
1
Quellcode-Link geändert für xunit.codeplex.com/SourceControl/changeset/view/…
Julien Roncaglia
1
Neuer Link in Kommentaren ebenfalls defekt.
Scott Stafford
1
Das Projekt wurde jetzt auf GitHub verschoben, aber ich konnte diese bestimmte Quelldatei dort auch nicht finden.
MEMark
1
Vergessen Sie für komplexe Objekte nicht, dass Sie einen Equal + GetHasCode benötigen, damit dies funktioniert, oder geben Sie der Equal-Methode einen benutzerdefinierten EqulityComparer
Maracuja-Saft
2
Die Methode xUnit Equal gibt für zwei IEnumerables mit gleichem Inhalt false zurück.
Vladimir Kocjancic
31

In der aktuellen Version von XUnit (1.5) können Sie nur verwenden

Assert.Equal (erwartet, tatsächlich);

Die obige Methode führt einen Element-für-Element-Vergleich der beiden Listen durch. Ich bin nicht sicher, ob dies für eine frühere Version funktioniert.

hwiechers
quelle
7
Das Problem, auf das ich bei Assert.Equal für Sammlungen gestoßen bin, besteht darin, dass es fehlschlägt, wenn die Elemente der Sammlungen in unterschiedlicher Reihenfolge vorliegen, auch wenn die Elemente in beiden vorhanden sind.
Scott Lawrence
1
@ ScottA.Lawrence Listen haben auch Ordnung! Erhalten Sie das gleiche Verhalten mit HashSets?
Johv
@johv Ich habe es nicht mit HashSets getestet, aber das ist eine gute Idee. Sobald ich die Gelegenheit hatte, es zu versuchen, werde ich versuchen, mich daran zu erinnern, hier zu antworten.
Scott Lawrence
2
Es scheint auch zu scheitern, wenn die Sammlungstypen unterschiedlich sind, selbst wenn beide dieselben Elemente in derselben Reihenfolge enthalten.
James White
3
Aber es hat eine sehr beschissene Ausgabe. Es sagt Ihnen nicht, wo sich zwei Listen unterscheiden! :(
Zordid
16

Wenn Sie mit xUnit die Eigenschaften jedes zu testenden Elements auswählen möchten, können Sie Assert.Collection verwenden.

Assert.Collection(elements, 
  elem1 => Assert.Equal(expect1, elem1.SomeProperty),
  elem2 => { 
     Assert.Equal(expect2, elem2.SomeProperty);
     Assert.True(elem2.TrueProperty);
  });

Dies testet die erwartete Anzahl und stellt sicher, dass jede Aktion überprüft wird.

Drew Williams
quelle
2

Vor kurzem habe ich meine asp.net core 2.2 App verwendet xUnit 2.4.0und Moq 4.10.1verpackt.

In meinem Fall habe ich es geschafft, es in zwei Schritten zum Laufen zu bringen:

  1. Definieren einer Implementierung von IEqualityComparer<T>

  2. Übergeben Sie die Vergleicherinstanz als dritten Parameter an Assert.Truemethod:

    Assert.True(expected, actual, new MyEqualityComparer());

Es gibt jedoch noch einen anderen besseren Weg, um mit dem FluentAssertions- Paket das gleiche Ergebnis zu erzielen . Damit können Sie Folgendes tun:

// Assert          
expected.Should().BeEquivalentTo(actual));

Interessanterweise Assert.Equal()schlägt das immer fehl, selbst wenn ich die Elemente von zwei Listen bestellt habe, um sie in derselben Reihenfolge zu erhalten.

Dmitry Stepanov
quelle
2
etwas stimmt nicht mit Ihrer Bestellung BeEquivalentTo kümmert sich nicht um die Bestellung (deshalb besteht Ihr Test mit BeEquivalentTo und nicht mit assert.Equal)
RagnaRock