Próbuję zapewnić, że jeden obiekt jest „równy” innemu obiektowi.
Obiekty są po prostu instancjami klasy z wieloma właściwościami publicznymi. Czy istnieje łatwy sposób, aby NUnit potwierdzał równość na podstawie właściwości?
To jest moje obecne rozwiązanie, ale myślę, że może być coś lepszego:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
To, do czego zmierzam, będzie w tym samym duchu, co CollectionEquivalentConstraint, w którym NUnit sprawdza, czy zawartość dwóch kolekcji jest identyczna.
źródło
IEnumerable
, zostanie porównany jako kolekcja, niezależnie od zastępowania implementacji,Equals
ponieważ NUnit dajeIEnumerable
wyższy priorytet. ZobaczNUnitEqualityComparer.AreEqual
metody, aby uzyskać szczegółowe informacje. Można przesłonić funkcję porównującą przy użyciu jednej zUsing()
metod ograniczenia równości . Nawet wtedy nie wystarczy zaimplementować nieogólnego,IEqualityComparer
ponieważ adapter używa NUnit.GetHashCode()
na zmiennych typach będzie źle działać, jeśli kiedykolwiek użyjesz tego obiektu jako klucza. IMHO, nadrzędneEquals()
,GetHashCode()
a co niezmiennych obiektów tylko do testowania nie ma sensu.Jeśli z jakiegokolwiek powodu nie możesz zastąpić Equals, możesz utworzyć metodę pomocniczą, która iteruje przez właściwości publiczne przez odbicie i potwierdzić każdą właściwość. Coś takiego:
źródło
Nie zastępuj Równa się tylko w celach testowych. Jest to żmudne i wpływa na logikę domeny. Zamiast,
Użyj formatu JSON, aby porównać dane obiektu
Brak dodatkowej logiki dla twoich obiektów. Brak dodatkowych zadań do testowania.
Po prostu użyj tej prostej metody:
Wydaje się, że działa świetnie. Informacje o wynikach programu uruchamiającego testy będą zawierać porównanie ciągów JSON (wykres obiektów), dzięki czemu od razu zobaczysz, co jest nie tak.
Zwróć też uwagę! Jeśli masz większe złożone obiekty i chcesz po prostu porównać ich części, możesz ( użyj LINQ do danych sekwencyjnych ) utworzyć anonimowe obiekty do użycia z powyższą metodą.
źródło
Wypróbuj bibliotekę FluentAssertions:
http://www.fluentassertions.com/
Można go również zainstalować za pomocą NuGet.
źródło
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Wolę nie zastępować Equals tylko po to, aby włączyć testowanie. Nie zapominaj, że jeśli nadpisujesz Equals, to naprawdę powinieneś również przesłonić GetHashCode, w przeciwnym razie możesz otrzymać nieoczekiwane wyniki, jeśli na przykład używasz swoich obiektów w słowniku.
Podobało mi się powyższe podejście do refleksji, ponieważ umożliwia dodawanie właściwości w przyszłości.
Jednak w celu szybkiego i prostego rozwiązania często najłatwiej jest utworzyć metodę pomocniczą, która sprawdza, czy obiekty są równe, lub zaimplementować IEqualityComparer w klasie, która jest prywatna dla testów. Korzystając z rozwiązania IEqualityComparer nie musisz przejmować się implementacją GetHashCode. Na przykład:
źródło
Wypróbowałem kilka podejść wymienionych tutaj. Większość obejmuje serializację obiektów i porównywanie ciągów. Chociaż jest to bardzo łatwe i ogólnie bardzo skuteczne, stwierdziłem, że jest trochę za krótki, gdy masz awarię i pojawia się coś takiego:
Ustalenie, gdzie są różnice, jest co najmniej uciążliwe.
Dzięki porównaniom grafów obiektów FluentAssertions (tj.
a.ShouldBeEquivalentTo(b)
) Otrzymujesz to z powrotem:To dużo przyjemniejsze. Pobierz FluentAssertions już teraz, będziesz zadowolony później (a jeśli zagłosujesz za tym, prosimy również o głosowanie za odpowiedzią dkl, gdzie FluentAssertions zostało po raz pierwszy zasugerowane).
źródło
Zgadzam się z ChrisYoxallem - implementowanie Equals w głównym kodzie wyłącznie do celów testowych nie jest dobre.
Jeśli implementujesz Equals, ponieważ wymaga tego pewna logika aplikacji, to jest w porządku, ale zachowaj czysty kod przeznaczony tylko do testów z dala od bałaganu (również semantyka sprawdzania tego samego do testowania może być inna niż to, czego wymaga Twoja aplikacja).
Krótko mówiąc, trzymaj kod przeznaczony tylko do testowania poza swoją klasą.
Proste, płytkie porównanie właściwości za pomocą odbicia powinno wystarczyć dla większości klas, chociaż może być konieczne powtórzenie, jeśli obiekty mają złożone właściwości. Jeśli stosujesz się do odnośników, uważaj na odnośniki cykliczne lub podobne.
Chytry
źródło
Ograniczenia właściwości , dodane w NUnit 2.4.2, pozwalają na rozwiązanie, które jest bardziej czytelne niż oryginalne rozwiązanie OP i generuje znacznie lepsze komunikaty o błędach. Nie jest to w żaden sposób ogólne, ale jeśli nie musisz tego robić dla zbyt wielu zajęć, jest to bardzo odpowiednie rozwiązanie.
Nie jest to tak ogólny cel, jak wdrażanie,
Equals
ale daje znacznie lepszy komunikat o błędzie niżźródło
Rozwiązanie JSON Maxa Wikstroma (powyżej) ma dla mnie największy sens, jest krótkie, przejrzyste i co najważniejsze działa. Osobiście jednak wolałbym zaimplementować konwersję JSON jako oddzielną metodę i umieścić potwierdzenie z powrotem w teście jednostkowym w ten sposób ...
METODA POMOCNICZA:
TEST JEDNOSTKOWY:
Do Twojej wiadomości - może być konieczne dodanie odwołania do System.Web.Extensions w swoim rozwiązaniu.
źródło
To dość stary wątek, ale zastanawiałem się, czy istnieje powód, dla którego nie zaproponowano odpowiedzi
NUnit.Framework.Is.EqualTo
iNUnit.Framework.Is.NotEqualTo
?Jak na przykład:
i
źródło
Inną opcją jest napisanie niestandardowego ograniczenia poprzez zaimplementowanie
Constraint
klasy abstrakcyjnej NUnit . Dzięki klasie pomocniczej, która dostarcza trochę cukru składniowego, wynikowy kod testu jest przyjemnie zwięzły i czytelny, np.Jako skrajny przykład rozważmy klasę, która ma członków „tylko do odczytu”, a nie jest
IEquatable
, i nie możesz zmienić testowanej klasy, nawet jeśli chcesz:Kontrakt dla
Constraint
klasy wymaga nadpisaniaMatches
iWriteDescriptionTo
(w przypadku niedopasowania narracja dla oczekiwanej wartości), ale także nadpisaniaWriteActualValueTo
(narracja dla rzeczywistej wartości) ma sens:Plus klasa pomocnicza:
Przykładowe użycie:
źródło
Oparłbym się na odpowiedzi @Juanma. Uważam jednak, że nie powinno się tego implementować z asercjami testów jednostkowych. Jest to narzędzie, które może być bardzo dobrze wykorzystane w pewnych okolicznościach przez kod niebędący testem.
Napisałem artykuł w tej sprawie http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Moja propozycja jest następująca:
Używanie tego z NUnit
zwraca następujący komunikat w przypadku niezgodności.
źródło
https://github.com/kbilsted/StatePrinter został napisany specjalnie w celu zrzucania grafów obiektów do reprezentacji ciągów w celu napisania łatwych testów jednostkowych.
Dany
Możesz w bezpieczny sposób i przy użyciu funkcji automatycznego uzupełniania programu Visual Studio uwzględnić lub wykluczyć pola.
źródło
Po prostu zainstaluj ExpectedObjects z Nuget, możesz łatwo porównać dwie wartości właściwości obiektów, każdą wartość obiektu kolekcji, dwie skomponowane wartości obiektu i częściowe porównanie wartości właściwości według typu anonimowego.
Mam kilka przykładów na github: https://github.com/hatelove/CompareObjectEquals
Oto kilka przykładów, które zawierają scenariusze porównywania obiektów:
Odniesienie:
źródło
Spójrz na poniższy link. Jest to rozwiązanie z projektu kodu i też z niego korzystałem. Działa dobrze przy porównywaniu obiektów.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
źródło
Skończyłem na napisaniu prostej fabryki wyrażeń:
i po prostu go użyj:
Jest to bardzo przydatne, ponieważ muszę porównać kolekcję takich obiektów. I możesz użyć tego porównania gdzie indziej :)
Oto sedno z przykładem: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
źródło
Zdeserializuj obie klasy i wykonaj porównanie ciągów.
EDYCJA: Działa doskonale, to jest wyjście, które otrzymuję z NUnit;
EDYTUJ DWA: Te dwa obiekty mogą być identyczne, ale kolejność serializacji właściwości nie jest taka sama. Dlatego XML jest inny. DOH!
EDYCJA TRZECIA: To działa. Używam go w moich testach. Musisz jednak dodać elementy do właściwości kolekcji w kolejności, w jakiej testowany kod je dodaje.
źródło
Wiem, że to naprawdę stare pytanie, ale NUnit nadal nie ma do tego natywnej obsługi. Jeśli jednak lubisz testy w stylu BDD (ala Jasmine), byłbyś mile zaskoczony NExpect ( https://github.com/fluffynuts/NExpect , pobierz to z NuGet), który ma wbudowane głębokie testy równości .
(zastrzeżenie: jestem autorem NExpect)
źródło
Określ i porównaj dwa ciągi
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
źródło
źródło