Testowanie prywatnych metod i pól – publicize.exe

W testach jednostkowych czasami warto testować również prywatne metody. Wynika to z zasady atomowości. Prywatne metody z reguły zawierają atomowe operacje, wykorzystywane potem w metodach publicznych. Jednym ze sposóbów jest użycie mechanizmu refleksji. W tym poście zajmiemy jednak się narzędziem publicize.exe, służącym do zmieniania modyfikatorów prywatnych na publiczne. Załóżmy, że mamy taką klasę:

class Klasa
{
   private int _PrywatnePoleA;
   private int _PrywatnePoleB;
   private event EventHandler Zdarzenie;
}

Uruchamiamy Visual Studio Command Prompt i wpisujemy:

publicize.exe NazwaBiblioteki.dll

Program wygeneruje nową bibliotekę, w której prywatne pola (_PrywatnePoleA, _PrywatnePoleB) będą dostępne jako publiczne. Wygenerowana biblioteka (NazwaBiblioteki_Accessor.dll) nazywana jest “Private Accessor”. Po podłączeniu do projektu, możemy przekonać się, że prywatne pola zostały zastąpione publicznymi:

ClassLibrary1.Klasa_Accessor klasa;
klasa._PrywatnePoleA = 3;
klasa._PrywatnePoleB = 6;

7 thoughts on “Testowanie prywatnych metod i pól – publicize.exe”

  1. Jeśli trzeba testować prywatne składowe klasy to znaczy, że coś mocno spieprzyliśmy. Odradzam i nie polecam. Jest z tym więcej problemów niż pożytku. Akcesory nie regenerują się same czasem i jak korzystamy z testów w kilka osób na wielu komputerach to ciągle ktoś się wkurza, że testy nie przechodzą.
    MS ze swoimi cudownymi narzędziami próbuje uszczęśliwić kiepskich programistów. To samo jest z mockowaniem statycznych składowych.

  2. Dlaczego?Testowanie prywatnych metod ma sens – wynika to z reguły atomowości. Zależy zresztą od szkoły. Ja osobiście testuje głównie publiczne metody a jeśli bym miał przetestować prywatną użyłbym refleksji a nie accessora ->mniej roboty.

    Czasami warto przetestować prywatne metody gdy publiczne wykonują naprawdę dużo operacji (np. wzorzec fasada).

  3. Dlaczego potrzebujesz testować coś co jest prywatne dla klasy? Masz taką potrzebę? Skoro nie jesteś w stanie przetestować prywatnych za pomocą publicznych to coś ostro skopałeś. Albo zapomniałeś o współpracownikach albo klasa robi za dużo.

    Gdy klasy wykonują dużo operacji to ich konstrukcja jest do bani 🙂 Gdzie SOLID? Fasadę też można ładnie napisać i potrzeby testowania prywatnych metod nie będzie. Jeśli piszesz niechlujny kod bez podejścia TDD to prędzej czy później skończysz z potrzebą testowania prywatnych metod. Pisząc kod wymuszany testami, zanim będziesz musiał testować prywatne pola / metody zdążysz się zorientować, że coś schrzaniłeś.

  4. W większości zgadzam się z SirMike’em. W projektach, w których wykorzystuje się testy jednostkowe, testowalność stanowi część wymagań względem tworzonego kodu i jest wyznacznikiem jego jakości. Najczęściej zresztą osiąga się ją tak samo, jak dobry kod: poprzez dążenie w kierunku luźnych powiązań i dużej zwartości, nie zaś w myśl „reguły atomowości”, cokolwiek należy rozumieć pod tym pojęciem.

    Trzeba wziąć pod uwagę również kwestię jakości testów jednostkowych. Dobry test powinien być odporny na zmiany kodu, który sprawdza. Przekłada się to na realne koszty. Nie osiągnie się tego silnie uzależniając się od szczegółów implementacji.

    Jest też druga strona medalu. Nie zawsze piszemy testy do kodu, na który mamy większy wpływ. W takiej sytuacji narzędzia takiej jak jak akcesory czy TypeMock Isolator potrafią być prawdziwym zbawieniem. Nie ma to jednak wiele wspólnego z pisaniem dobrego kodu.

  5. @SirMike:
    To nie jest kwestia pisania dobrego kodu czy nie. Jeśli korzysta sie z metryk naprawdę trudno o martwy kod – nawet jesli jest wielki balagan.
    Ponadto wszystko fajnie wyglada teoretycznie. W praktyce nierzadko testujemy nie swoj kod.

    Istnieja generalnie dwie szkoly. Jedni testuja metody prywatne a drudzy nie. Ja uwazam, ze powinno korzystac sie z kompromisu – generalnie publiczne metody (najlatwiej, najbezpieczniej,najszybciej) ale czasami sa wyjatki.TDD jest dobre dla nowych projektow…

  6. @apl:
    regula atomowosci… No coz, moze spolszczenie malo trafne ale atomic strcture to chyba najwazniejsza regula pisania testow jednostkowych.I to jest nawazniejszy argument tej szkoly polecajec testowanie niektorych metod prywatnych (np. metoda wykonujaca skomplikowane obliczenia).

  7. @Piotr: Ależ jak najbardziej jest 🙂 Rozumiem, że możemy dostać tzw. “kod spadkowy” i wtedy, jak wspomniał apl, narzędzia typu Type MockIsolator są zbawieniem. Jednak ciężko mi wyobrazić sobie testowanie pól prywatnych wymuszony racjonalnym podejściem do tworzonego kodu.

    Mógłbyś pokazać mi *rzeczywisty* kod (nie jakieś akademickie przykłady albo MSDN), gdzie będziesz potrafił uzasadnić testowanie pól prywatnych? Bo testowanie nieswojego kodu to trochę patologia 🙂 Patologia uwielbiana przez duże firmy, które stać na rozróżnienie programisty od testera. To, że musimy testować prywatne składowe jakiegoś programisty z innego działu nie usprawiedliwia tego, że kod jest do bani 😉

    Metryki? Pokażą Ci, że tak, coś masz zwalone… po fakcie 🙂

Leave a Reply

Your email address will not be published.