Zastanawiam się, jak prawidłowo korzystać z NUnit. Najpierw utworzyłem oddzielny projekt testowy, który używa mojego projektu głównego jako odniesienia. Ale w takim przypadku nie jestem w stanie przetestować prywatnych metod. Zgadłem, że muszę dołączyć kod testowy do kodu głównego ?! - To nie wydaje się być właściwym sposobem, aby to zrobić. (Nie podoba mi się pomysł wysyłania kodu z testami).
Jak testujesz prywatne metody za pomocą NUnit?
c#
unit-testing
testing
nunit
MrFox
źródło
źródło
System.Reflection
umożliwia dostęp i wywoływanie metod niepublicznych za pomocą flag wiązania, więc możesz zhakować NUnit lub skonfigurować własną strukturę. Lub (myślę, że łatwiej), możesz ustawić flagę czasu kompilacji (#if TESTOWANIE), aby zmienić modyfikatory dostępu, umożliwiając korzystanie z istniejących frameworków.Chociaż zgadzam się, że testowanie jednostkowe powinno skupiać się na interfejsie publicznym, uzyskasz znacznie bardziej szczegółowy obraz swojego kodu, jeśli przetestujesz również metody prywatne. Framework testowy MS pozwala na to poprzez użycie PrivateObject i PrivateType, NUnit tego nie robi. Zamiast tego robię:
W ten sposób nie musisz rezygnować z enkapsulacji na rzecz testowalności. Pamiętaj, że musisz zmodyfikować BindingFlags, jeśli chcesz przetestować prywatne metody statyczne. Powyższy przykład to tylko przykładowe metody.
źródło
Typowym wzorcem pisania testów jednostkowych jest testowanie tylko metod publicznych.
Jeśli okaże się, że masz wiele metod prywatnych, które chcesz przetestować, zwykle jest to znak, że należy zreformować kod.
Byłoby błędem upublicznianie tych metod w klasie, w której obecnie mieszkają. To złamałoby kontrakt, który chcesz, aby ta klasa miała.
Poprawne może być przeniesienie ich do klasy pomocników i upublicznienie ich tam. Ta klasa może nie być ujawniona przez Twój interfejs API.
W ten sposób kod testowy nigdy nie jest mieszany z kodem publicznym.
Podobnym problemem jest testowanie zajęć prywatnych tj. klasy, których nie eksportujesz z zestawu. W takim przypadku możesz jawnie uczynić swój zestaw kodu testowego przyjacielem zestawu kodu produkcyjnego przy użyciu atrybutu InternalsVisibleTo.
źródło
Możliwe jest przetestowanie metod prywatnych przez zadeklarowanie zestawu testowego jako zestawu znajomego testowanego zestawu docelowego. Zobacz poniższe łącze, aby uzyskać szczegółowe informacje:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
Może to być przydatne, ponieważ w większości przypadków oddziela kod testowy od kodu produkcyjnego. Sam nigdy nie korzystałem z tej metody, ponieważ nigdy nie znalazłem takiej potrzeby. Przypuszczam, że możesz go użyć do wypróbowania ekstremalnych przypadków testowych, których po prostu nie możesz odtworzyć w swoim środowisku testowym, aby zobaczyć, jak obsługuje to Twój kod.
Jak już powiedziano, naprawdę nie powinieneś testować prywatnych metod. Bardziej niż prawdopodobne jest, że chcesz zrefaktoryzować swój kod na mniejsze bloki konstrukcyjne. Jedna wskazówka, która może ci pomóc, gdy przyjdziesz do refaktoryzacji, to spróbować pomyśleć o domenie, do której odnosi się twój system, i pomyśleć o „prawdziwych” obiektach zamieszkujących tę domenę. Twoje obiekty / klasy w twoim systemie powinny odnosić się bezpośrednio do rzeczywistego obiektu, co pozwoli ci wyodrębnić dokładne zachowanie, które powinien zawierać obiekt, a także ograniczy odpowiedzialność za obiekty. Będzie to oznaczać, że refaktoryzujesz się logicznie, a nie tylko po to, aby umożliwić przetestowanie określonej metody; będziesz mógł przetestować zachowanie obiektów.
Jeśli nadal czujesz potrzebę testowania wewnętrznego, możesz również rozważyć mockowanie w testowaniu, ponieważ prawdopodobnie będziesz chciał skupić się na jednym fragmencie kodu. Mockowanie polega na wstrzyknięciu do niego zależności obiektów, ale wstrzyknięte obiekty nie są „rzeczywistymi” ani obiektami produkcyjnymi. Są to pozorne obiekty, których zachowanie zostało zakodowane na stałe, aby ułatwić wyodrębnienie błędów behawioralnych. Rhino.Mocks to popularny, darmowy framework do mockowania, który zasadniczo zapisze obiekty za Ciebie. TypeMock.NET (produkt komercyjny z dostępną edycją społeczności) to bardziej zaawansowana struktura, która może symulować obiekty CLR. Bardzo przydatne do mockowania klas SqlConnection / SqlCommand i Datatable na przykład podczas testowania aplikacji bazy danych.
Mam nadzieję, że ta odpowiedź dostarczy Ci nieco więcej informacji, które pomogą Ci uzyskać ogólne informacje o testach jednostkowych i pomogą Ci uzyskać lepsze wyniki z testów jednostkowych.
źródło
Jestem zwolennikiem możliwości testowania metod prywatnych. Kiedy xUnit został uruchomiony, był przeznaczony do testowania funkcjonalności po napisaniu kodu. W tym celu wystarczy przetestowanie interfejsu.
Testowanie jednostkowe ewoluowało w kierunku programowania opartego na testach. Możliwość testowania wszystkich metod jest przydatna w tej aplikacji.
źródło
To pytanie jest w podeszłym wieku, ale pomyślałem, że podzielę się swoim sposobem zrobienia tego.
Zasadniczo mam wszystkie moje klasy testów jednostkowych w zestawie, który testują, w przestrzeni nazw `` UnitTest '' poniżej `` domyślnej '' dla tego zestawu - każdy plik testowy jest opakowany w:
block, a wszystko to oznacza, że a) nie jest rozpowszechniany w wydaniu i b) mogę używać deklaracji
internal
/Friend
level bez przeskakiwania przez pętlę.Inną rzeczą, którą to oferuje, bardziej związaną z tym pytaniem, jest użycie
partial
klas, które można wykorzystać do utworzenia proxy do testowania metod prywatnych, na przykład do przetestowania czegoś takiego jak metoda prywatna, która zwraca wartość całkowitą:w głównych klasach montażu oraz w klasie testowej:
Oczywiście musisz upewnić się, że nie używasz tej metody podczas programowania, chociaż kompilacja wydania wkrótce wskaże niezamierzone wywołanie jej, jeśli to zrobisz.
źródło
Głównym celem testów jednostkowych jest testowanie publicznych metod klasy. Te metody publiczne będą wykorzystywać te metody prywatne. Testy jednostkowe sprawdzą zachowanie tego, co jest publicznie dostępne.
źródło
Przepraszamy, jeśli to nie odpowiada na pytanie, ale rozwiązania takie jak użycie refleksji, stwierdzeń #if #endif lub pokazanie prywatnych metod nie rozwiązują problemu. Może być kilka powodów, dla których metody prywatne nie są widoczne ... co, jeśli jest to kod produkcyjny, a zespół na przykład retrospektywnie pisze testy jednostkowe.
W przypadku projektu, nad którym pracuję, tylko MSTest (niestety) wydaje się mieć sposób, przy użyciu akcesorów, na testowanie prywatnych metod jednostkowych.
źródło
Nie testujesz funkcji prywatnych. Istnieją sposoby wykorzystania refleksji, aby dostać się do prywatnych metod i właściwości. Ale to nie jest łatwe i zdecydowanie odradzam tę praktykę.
Po prostu nie powinieneś testować niczego, co nie jest publiczne.
Jeśli masz jakieś wewnętrzne metody i właściwości, powinieneś rozważyć zmianę ich na publiczne lub wysłanie testów z aplikacją (coś, co tak naprawdę nie widzę jako problemu).
Jeśli Twój klient jest w stanie uruchomić Test-Suite i widzi, że dostarczony przez Ciebie kod faktycznie „działa”, nie widzę w tym problemu (o ile nie podasz w ten sposób swojego adresu IP). W każdym wydaniu zamieszczam raporty z testów i raporty pokrycia kodu.
źródło
W teorii testów jednostkowych należy testować tylko kontrakt. tzn. tylko publiczni członkowie klasy. Ale w praktyce deweloper zwykle chce przetestować członków wewnętrznych. - i nie jest źle. Tak, jest to sprzeczne z teorią, ale w praktyce czasami może się przydać.
Jeśli więc naprawdę chcesz przetestować członków wewnętrznych, możesz użyć jednego z następujących podejść:
Przykład kodu (pseudokod):
źródło
Message: Method is not public
.Możesz uczynić swoje metody chronionymi wewnętrznymi, a następnie użyć
assembly: InternalsVisibleTo("NAMESPACE")
do testowej przestrzeni nazw.Dlatego NIE! Nie możesz uzyskać dostępu do metod prywatnych, ale jest to obejście.
źródło
Uczyniłbym widoczny pakiet metod prywatnych. W ten sposób zachowasz rozsądną prywatność, a jednocześnie będziesz w stanie przetestować te metody. Nie zgadzam się z ludźmi, którzy twierdzą, że interfejsy publiczne są jedynymi, które powinny być testowane. W metodach prywatnych często znajduje się naprawdę krytyczny kod, którego nie można poprawnie przetestować, przechodząc tylko przez zewnętrzne interfejsy.
Więc to naprawdę sprowadza się do tego, czy bardziej zależy ci na poprawnym kodzie lub ukrywaniu informacji. Powiedziałbym, że widoczność pakietu jest dobrym kompromisem, ponieważ aby uzyskać dostęp do tej metody, ktoś musiałby umieścić swoją klasę w Twoim pakiecie. To powinno naprawdę skłonić ich do zastanowienia się, czy to naprawdę mądra rzecz.
Tak przy okazji, jestem facetem od Javy, więc widoczność pakietu można nazwać czymś zupełnie innym w C #. Wystarczy powiedzieć, że dwie klasy muszą znajdować się w tej samej przestrzeni nazw, aby uzyskać dostęp do tych metod.
źródło