środa, 17 listopada 2010

PowerMock

Powermock to narzędzie rozszerzające możliwości innych bibliotek do mockowania - Mockito i EasyMocka.
Nie jest to nowa biblioteka a jedynie kilka nowych funkcjonalności, które działają na dobrze znanym API.

PowerMock potrafi to, czego nie potrafią zwykłe biblioteki (te bez Powera w nazwie):
  1. mockować statyczne metody
  2. mockować klasy finalne
  3. mockować prywatne metody
  4. mockować konstruktory
  5. wyłączać zachowanie inicjalizatorów
  6. i parę innych rzeczy


1. Metody statyczne

Ortodoksi pewnie powiedzą "jeśli musisz mockować statyczne metody to prawdopodobnie masz zły design".
Każda aplikacja integruje się z różnymi zewnętrznymi bibliotekami i frameworkami. Jeśli framework z którego chcemy korzystać posiada API oparte na statycznych wywołaniach mamy dwie podstawowe opcje jeśli chodzi o testowanie:
  1. Stworzyć fasadę zewnętrznego API, która nie jest statyczna i którą łatwo wykorzystać we własnych testach.
    Plusy:
    • łatwo testować interakcje z zewnętrznym API
    • aplikacja nie jest zależna od zewnętrznego API i w razie potrzeby jego zmiany/wymiany wystarczy przepisać warstwę fasady

    Minusy:
    • Mamy dodatkową, może niepotrzebną z innych względów, warstwę, którą trzeba stworzyć i utrzymywać

  2. Użyć PowerMocka i bezpośrednio testować interakcję ze statycznym API. Na potrzeby testów nie wprowadzamy żadnych dodatkowych artefaktów do kodu.

Decyzję każdy musi podjąć samemu.

Zamockowanie statycznych metod wymaga jednej adnotacji nad testem
@PrepareForTest(UserManager.class)

oraz dwóch linii kodu w celu zadeklarowania zachowania:
PowerMockito.mockStatic(UserManager.class);
Mockito.when(UserManager.getCurrentUser()).thenReturn(admin);

Zweryfikowanie wywołania również wymaga dwóch linii kodu:
PowerMockito.verifyStatic();
NastyStatic.getCurrentUser();

Jest to trochę mniej wygodne i czytelne od zwykłego Mockitowego when() i verify().

2. Klasy finalne

Niemożliwość mockowania klas finalnych jest niewygodnym ograniczeniem Mockito. Jako że Powermock nie używa Proxies do klas tylko własnego classloadera - można to dzięki niemu osiągnąć.

3. Metody prywatne

PowerMock umożliwia również mockowanie prywatnych metod. Niestety tracimy tutaj wygodne API z Mockito, bo trzeba zdefiniować nazwę metody w parametrze. Zadeklarowanie zachowania prywatnej metody bezargumentowej wygląda np. tak:
doReturn("it's private").when(testedObject, "getPrivateString", new Object[0]);

a weryfikacja czy została zawołana
verifyPrivate(testedObject).invoke("getPrivateString", new Object[0]);

Osobiście nie podobają mi się takie konstrukcje w kodzie, dlatego też nie widzę tutaj żadnej wartości PowerMocka.

4. Konstruktory

Mockowanie konstrukcji obiektów jest dość ciekawym pomysłem.
Możemy dzięki niemu nawet zweryfikować ile obiektów danej klasy jest tworzonych:
PowerMockito.verifyNew(MyClass.class, times(10)).withNoArguments();

w tym przykładzie sprawdzamy, że zostało powołanych dokładnie 10 instancji klasy MyClass.


5. Wyłączanie fragmentów kodu

Wyłączanie inicjalizatorów i konstruktorów może być przydatne, gdy konstruktor nadklasy jest 'zły' i wykonuje jakieś akcje, które w teście rzucają wyjątek. Zgodnie z zasadą, aby nie wykonywać pracy w konstruktorze chcielibyśmy pominąć to zachowanie w naszych testach.
Do tego wystarczy przed powołaniem instancji tej klasy wykonać:
PowerMockito.suppress(PowerMockito.constructor(EvilClass.class));

spowoduje to również, że kod z bloku inicjalizującego się nie wykona.

możemy również wyłączyć wykonanie statycznego bloku inicjalizującego poprzez adnotację na klasie testu:
@SuppressStaticInitializationFor("com.evil.EvilClass")


Podsumowując:

PowerMock jest fajnym rozszerzeniem do Mockito czy EasyMocka. Może być przydatny tam, gdzie chcemy testować dobry kod, który musi być w interakcji z innym, trochę gorszym kodem. Warto rozważyć, czy to nie lepsze od pisania własnej fasady dostępu do zewnętrznego API.
Ponadto możliwość mockowania klas finalnych jest czymś, co umila życie nie prowadząc za sobą żadnych efektów ubocznych.

Szkolenie TDD - ostatnie miejsca

Nasze szkolenie TDD cieszy się dość dużym zainteresowaniem, więc ponad połowy miejsc już nie ma. Zainteresowanych zachęcam więc do szybkiej decyzji, tym bardziej, że zmiany VAT powodują, że od nowego roku szkolenia nie będą jak dotychczas zwolnione, lecz będą opodatkowane nową stawką 23%, co podniesie znacząco ich koszt.
O ile nie skończą się wolne miejsca, rejestrację zamykamy za 2 tygodnie.

wtorek, 2 listopada 2010

Nowa strona szkoleń & szkolenie TDD

Wystartowaliśmy z nową stroną dotyczącą prowadzonych przez nas szkoleń. Zawiera trochę więcej informacji o naszej ofercie szkoleniowej niż jej poprzednia wersja, poza tym wygląda "bardziej".

Poza tym startujemy z rejestracją na szkolenie TDD, które odbędzie się 6-8 grudnia. Można więc sobie zrobić miły prezent mikołajkowy :-) Szczegóły i rejestracja na stronie szkolenia. Zapraszamy!

Przy okazji chcemy poinformować, że Warsjawowy konkurs o miejscówkę na tym szkoleniu wygrał Jacek Złydach.