Jestem całkiem początkującym w testowaniu kodu, a wcześniej byłem assert
dziwką. Jedną z rzeczy, która mnie martwi w testach jednostkowych, jest to, że często wymaga to od ciebie public
(lub przynajmniej internal
) wypełnienia pól, które byłyby private
inaczej, usunięcia readonly
ich, zamiast tego stworzenia private
metod protected virtual
itp.
Niedawno odkryłem, że można tego uniknąć, używając rzeczy takich jak klasa PrivateObject, aby uzyskać dostęp do czegokolwiek w obiekcie poprzez odbicie. Ale to sprawia, że twoje testy są mniej łatwe w utrzymaniu (rzeczy zawiedzie podczas wykonywania niż kompilacji czasu, zostanie zepsute przez zwykłą zmianę nazwy, trudniej jest debugować ...). Jaka jest twoja opinia na ten temat ? Jakie są najlepsze praktyki w testowaniu jednostkowym dotyczące ograniczenia dostępu?
edytuj: rozważ na przykład, że masz klasę z pamięcią podręczną w pliku na dysku, aw testach zamiast tego chcesz zapisać w pamięci.
źródło
Odpowiedzi:
Nigdy nie powinieneś
Zwłaszcza nieprzyłączenie pola może spowodować, że niezmienny obiekt będzie podlegał modyfikacji, a to byłaby katastrofa.
Twoje testy powinny traktować twoje obiekty jako czarne skrzynki ( Wikipedia ), co oznacza, że powinny one dotyczyć wyłącznie publicznego interfejsu obiektów, a nie szczegółów ich implementacji.
Jeśli obiektu nie można wystarczająco przetestować przy użyciu jego publicznego interfejsu, musisz znaleźć sposoby na zapewnienie formalnych i użytecznych rozszerzeń jego interfejsu, które ułatwiłyby testowanie. Na przykład system rejestracji wykorzystujący tylko parę metod rejestracji / wyrejestrowania mógłby skorzystać z metody IsRegistered, nawet jeśli nie jest to konieczne dla danego wniosku; nadal jest to formalne i użyteczne rozszerzenie interfejsu, a nawiasem mówiąc, będzie mogło pomieścić testy.
Ważne jest to, że zmiana implementacji obiektu nie powinna wymagać zmiany testu jednostkowego. Teoretycznie powinieneś być w stanie napisać test jednostkowy raz, a następnie poprosić wielu programistów o zakodowanie wielu całkowicie różnych implementacji testowanego obiektu do pracy z testem jednostkowym.
źródło
private
metodprotected virtual
pomagających w kpinach w testach jest uważane za złą praktykę?W C # możesz użyć
InternalsVisibleToAttribute
aby umożliwić zestawowi testowemu zobaczyćinternal
klasy w zestawie, który testujesz. Wygląda na to, że już to wiesz.W większości przypadków jestem zainteresowany testowaniem publicznego interfejsu API mojego zestawu. W przypadku, gdy chcę wykonać testy białych jednostek dla niektórych jednostek, przenoszę kod do
internal
klasy i ustawiampublic
metodę tej klasy. Następnie mogę zakodować test jednostkowy dla tej klasy.To dobrze nadaje się do wstrzykiwania zależności i wzorca strategii. Możesz wyodrębnić metodę do interfejsu, wstrzyknąć interfejs do konstruktora obiektu nadrzędnego i po prostu przetestować, czy rodzic odpowiednio deleguje. Następnie możesz przetestować, czy obiekt potomny zachowuje się odpowiednio. Dzięki temu wszystko jest bardziej modułowe.
źródło
Z mojego doświadczenia najlepiej nie wystawiać wewnętrznych elementów twojej klasy specjalnie na test. Chociaż może się to wydawać, aby test był łatwiejszy do napisania. Test jest pierwszym klientem twojej klasy, więc jeśli trudno jest przetestować klasę za pomocą publicznego interfejsu, prawdopodobnie trudno będzie użyć twojej klasy również w innych miejscach.
Jak łatwo jest przetestować klasę za pomocą publicznego interfejsu API, jest informacja zwrotna na temat tego, jak łatwa będzie klasa. Pomyśl o testach częściowo jako o prototypie użycia twojej klasy.
Zastanów się, dlaczego twój test musi wykryć coś o klasie, która nie jest dostępna za pośrednictwem publicznego interfejsu API. Być może twoja klasa robi za dużo i zamiast tego musi zostać podzielona na grupę klas współpracujących? Następnie możesz wyśmiewać niektóre ze współpracujących klas, aby wyczuć, co robi testowana klasa.
Spróbuj zastosować zasadę inwersji zależności i wprowadzić interfejsy między klasami, które możesz wyśmiewać w testach. Możesz podać współpracowników do testu, stosując odwrócenie kontroli .
Zastanów się także nad zastosowaniem zasady „mów nie pytaj”, aby ustrukturyzować interfejs swojej klasy w solidny, luźno powiązany sposób, w którym odpowiednie informacje są ujawniane, a reszta jest ukryta.
źródło
Osobiście wolę zostawić kod, który testuję tak czysto, jak to tylko możliwe, a jeśli kod testowy wymaga włamań (oraz w paskudnych wskaźnikach w C ++ itp.) Jestem szczęśliwy, że mogę to zrobić.
źródło
Widoczność kodu nie ma nic wspólnego z testami jednostkowymi!
Czynisz swoje metody prywatnymi, a nie po to, by ukrywać je przed testowaniem, i nie upubliczniasz ich do testowania, prawda? To wasza implementacja jest tutaj niezbędna, a nie testy - te serwery są dowodem twojego kodu, ale nie są twoim kodem .
Istnieje wiele sposobów, aby umożliwić dostęp do ukrytych (prywatnych lub wewnętrznych) metod i właściwości. Wiele frameworków testowych i IDE (na przykład Visual Studio) obsługuje cię tutaj, generując wszystko, co jest potrzebne do uzyskania dostępu, musisz tylko stworzyć swoje przypadki testowe. Dlaczego więc się martwić? Lepiej utrzymuj kod w czystości i porządku.
źródło