xUnit: Assert dwa List <T> są równe?

109

Jestem nowy w TDD i xUnit, więc chcę przetestować moją metodę, która wygląda mniej więcej tak:

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

Czy jest jakaś metoda Assert, której mogę użyć? Myślę, że coś takiego byłoby fajne

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

Czy jest coś takiego?

Petar Petrov
źródło

Odpowiedzi:

137

xUnit.Net rozpoznaje kolekcje, więc po prostu musisz to zrobić

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

Możesz zobaczyć inne dostępne potwierdzenia kolekcji w CollectionAsserts.cs

W przypadku NUnit metody porównawcze kolekcji to

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

i

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

Więcej szczegółów tutaj: CollectionAssert

MbUnit ma również potwierdzenia kolekcji podobne do NUnit: Assert.Collections.cs

Konstantin Spirin
źródło
1
Link do kodu źródłowego został zmieniony dla xunit.codeplex.com/SourceControl/changeset/view/ ...
Julien Roncaglia
1
Nowy link w komentarzach też jest uszkodzony.
Scott Stafford
1
Projekt został przeniesiony do GitHub, ale tam też nie mogłem znaleźć tego konkretnego pliku źródłowego.
MEMark
1
W przypadku złożonych obiektów nie zapominaj, że potrzebujesz kodu Equal + GetHasCode, aby to zadziałało, lub nadaj metodzie Equal niestandardowy EqulityComparer
maracuja-juice
2
Metoda xUnit Equal zwraca wartość false dla dwóch elementów IEnumerables o równej zawartości.
Vladimir Kocjancic,
31

W obecnej wersji XUnit (1.5) możesz po prostu użyć

Assert.Equal (oczekiwany, rzeczywisty);

Powyższa metoda wykona porównanie element po elemencie obu list. Nie jestem pewien, czy to działa w przypadku jakiejkolwiek wcześniejszej wersji.

hwiechers
źródło
8
Problem, który napotkałem w przypadku Assert.Equal dla kolekcji, polega na tym, że kończy się niepowodzeniem, jeśli elementy kolekcji są w różnych kolejności, nawet jeśli elementy są obecne w obu.
Scott Lawrence,
1
@ ScottA. Lawrence Listy też mają porządek! Czy masz takie samo zachowanie w przypadku HashSets?
johv
@johv Nie testowałem tego z HashSets, ale to dobry pomysł. Kiedy już będę miał okazję tego spróbować, postaram się pamiętać o odpowiedzi tutaj.
Scott Lawrence,
2
Wydaje się również, że kończy się niepowodzeniem, jeśli typy kolekcji są różne, nawet jeśli oba zawierają te same elementy w tej samej kolejności.
James White
3
Ale ma bardzo kiepski wynik. Nie mówi ci, GDZIE różnią się dwie listy! :(
Zordid
17

W przypadku xUnit, jeśli chcesz wybrać najlepsze właściwości każdego elementu do przetestowania, możesz użyć Assert.Collection.

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

To sprawdza oczekiwaną liczbę i zapewnia, że ​​każda akcja jest zweryfikowana.

Drew Williams
źródło
2

Ostatnio używałem xUnit 2.4.0i Moq 4.10.1pakietów w mojej aplikacji asp.net core 2.2.

W moim przypadku udało mi się to zadziałać w dwóch etapach:

  1. Zdefiniowanie implementacji IEqualityComparer<T>

  2. Przekaż instancję porównującą jako trzeci parametr do Assert.Truemetody:

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

Ale jest inny przyjemniejszy sposób na uzyskanie tego samego wyniku przy użyciu pakietu FluentAssertions . Umożliwia wykonanie następujących czynności:

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

Co ciekawe, to Assert.Equal()zawsze zawodzi, nawet jeśli zamówiłem elementy dwóch list, aby uzyskać je w tej samej kolejności.

Dmitrij Stiepanow
źródło
2
coś jest nie tak z twoim zamówieniem BeEquivalentTo nie dba o porządek (dlatego twój test przechodzi z BeEquivalentTo, a nie z assert.Equal)
RagnaRock