Jaki jest idiomatyczny sposób weryfikacji rozmiaru kolekcji w xUnit?

112

Mam w swoim zestawie testów test, który wygląda mniej więcej tak:

[Fact]
public void VerifySomeStuff()
{
    var stuffCollection = GetSomeStuff();

    Assert.Equal(1, stuffCollection.Count());
}

Ten test działa zgodnie z oczekiwaniami, ale kiedy go uruchamiam, xUnit wyświetla ostrzeżenie:

ostrzeżenie xUnit2013: Nie używaj funkcji Assert.Equal () do sprawdzania rozmiaru kolekcji.

Jednak ostrzeżenie nie sugeruje żadnej alternatywy, a wyszukiwarka Google przenosi mnie do kodu źródłowego w xUnit w celu wydrukowania testu, który weryfikuje to ostrzeżenie.

Jeśli Assert.Equal()nie jest to właściwy sposób sprawdzenia długości kolekcji, to co to jest?


Dla wyjaśnienia: zdaję sobie sprawę, że mógłbym „oszukać” xUnit, aby nie emitował tego ostrzeżenia, np. Wyodrębniając zmienną lub używając Assert.True(stuff.Count() == 1)zamiast tego. To drugie jest po prostu hacky, a pierwsze wydaje się, że jeśli xUnit próbuje np. Uniknąć wielu iteracji an IEnumerable<T>, to jest to niewłaściwa droga (ponieważ otrzymam wskazówki kompilatora na ten temat osobno, jeśli jest to problem), i xUnit Sama nigdy nie powinna musieć oceniać danych wejściowych więcej niż raz (w rzeczywistości prawdopodobnie otrzyma te same dane wejściowe niezależnie od wyodrębniania zmiennych, ze względu na to, jak działa wywołanie funkcji C #).

Nie jestem więc zainteresowany tylko usunięciem tego ostrzeżenia z moich wyników. Odpowiedź na moje pytanie wyjaśnia również, dlaczego to ostrzeżenie jest zawarte w bibliotece w pierwszej kolejności i dlaczego jakiekolwiek podejście, które powinienem zastosować, jest lepsze.

Tomas Aschan
źródło
jeśli przechowujesz stuffCollection.Count()w osobnej zmiennej i przekazujesz ją do potwierdzenia, czy daje to ten sam błąd?
hellyale
Może ten ?
Uwe Keim

Odpowiedzi:

113

Xunit oferuje szybkie poprawki dla większości swoich ostrzeżeń, więc powinieneś być w stanie zobaczyć, co uważa za „właściwe”.

xunit

W twoim przypadku chce, abyś użył, Assert.Singleponieważ oczekujesz dokładnie jednego przedmiotu. Gdybyś podawał dowolną liczbę, na przykład 412, nie dałoby to ostrzeżenia o użyciu Count. Zasugeruje użycie tylko Singlewtedy, gdy spodziewasz się jednego przedmiotu lub Emptyjeśli nie spodziewasz się żadnych przedmiotów.

vcsjones
źródło
6
Dzięki, to ma sens. FWIW, widziałem to podczas budowania w VS Code, w którym szybkie działanie nie pojawiło się, więc uwzględnienie sugestii poprawki w komunikacie ostrzegawczym byłoby znacznie bardziej pomocne.
Tomas Aschan
2
@TomasLycken - ah. Tak, jest tutaj problem: github.com/xunit/xunit/issues/1423
vcsjones
5
Nie jestem fanem takiego zachowania; czasami liczba 1 jest tylko przypadkowa i wymuszenie wywołania .Single () wydaje się mniej wyraziste. Test może się zmienić, aby spodziewać się innej liczby, i wydaje się denerwujące, że trzeba wprowadzić zmianę, aby wywołać zupełnie inną metodę, zamiast po prostu zmienić liczbę.
vargonian
2
Pojedynczy jest fajny dla pojedynczego przedmiotu, mam 3 elementy i nie chcę pisać pełnego Assert.Collection, czy xUnit ma Assert.Triple? haha
Paweł Cioch
1
@PawelCioch zgodnie z xunit.net/xunit.analyzers/rules/xUnit2013.html, które mają Empty, Singlei NotEmpty- jeśli spodziewasz się wartości dynamicznej, xUnit2013 nie powinno wyzwalać.
mbx
2

Znalazłem to, daj mi ten sam błąd:

Assert.Equal(2, vm.Errors.Count());

Przesyłanie go powstrzymało pojawienie się błędu.

Assert.Equal(2, (int)vm.Errors.Count());
devjc
źródło
2
Jestem pewien, to nie ideomatic sposób.
mbx
1

W przypadku pojedynczego elementu na liście najlepiej jest użyć tego: Assert.Single(resultList);

Bosco Han
źródło
-1

Miałem ten sam problem, gdy użyłem właściwości Count, jak poniżej w xUnit.

wprowadź opis obrazu tutaj

Później używam funkcji Count () w kolekcji, rozwiązało to mój problem.

Bhuwan Maharjan
źródło
Naprawiono problem, ale nadal nie używasz XUnit tak, jak powinieneś!
Daniel Eisenreich,
8
@DanielEisenreich Jaki jest prawidłowy sposób potwierdzania liczby dla określonej liczby, jeśli jest większa niż 1?
SomeGuyOnAComputer
@SomeGuyOnAComputer i pozostałe 4 głosy za. Zapomnij, co powiedziałem, byłem zbyt bezczelny. Jeśli jest większy, nie masz innego wyboru.
Daniel Eisenreich