- klasyczne, gdzie wykorzystuje się prawdziwe obiekty, jeśli można
- z wykorzystaniem obiektów pozornych (Mock objects)
Takie podejście w projektach opartych o architekturę MVC, do których oczywiście zaliczają się Grailsy, jest bardzo przydatne m.in. w kontrolerach, które zwykle operują na obiektach klas domenowych czy też serwisów. Dzięki zastosowaniu mocków możemy łatwo sprawdzić czy kontroler wykonuje powierzone mu zadania i nie jesteśmy uzależnieni od faktycznej implementacji innych warstw.
Dzięki dynamiczności języka Groovy, obiekty pozorne można tworzyć bez użycia wyspecjalizowanych frameworków, jednakże jest to dość niewygodne. Powstało kilka projektów mających na celu uczynienie tego łatwiejszym. Jeden z nich (MockFor) jest zintegrowany w Groovy on Grails, jednakże mi osobiście nie podpasował. Wobec czego polecam Gmock, z którego sam także korzystam.
Instalacja Gmock w projekcie Grails nie jest skomplikowana, jednakże aktualnie nie istnieje żaden plugin, który bo to jeszcze ułatwiał. Skorzystamy, więc z Mavena i pliku conf/BuildConfig.groovy. W sekcji odpowiadającej za dependencies dopisujemy:
test 'org.gmock:gmock:0.8.1'Aby wykorzystać Gmock w swoim teście możemy zastosować jedną z 3 metod:
- dziedziczyć po klasie GMockTestCase (to jest opisane w dokumentacji Gmock, jednakże to podejście nie jest najlepsze z różnych przyczyn, więc nie będę go szerzej opisywał)
- dodać adnotację @WithGMock do klasy testu (to jest najfajniejsze rozwiązanie, jednakże w aktualnej wersji nie działa z Grails 2.0)
- użyć obiektu typu GMockController()
Tworzenie obiektów pozornych jest bardzo łatwe i opiera się na prostym DSL stworzonym w tym celu.
I tak dla klasy SpringSecurityService tworzymy go w następujący sposób:
def springSecurityMock = gmock.mock(SpringSecurityService)W ten sposób mamy utworzony obiekt pozorny, jednakże jeszcze bez żadnych metod, czy też sprawdzania warunków. Aby dodać warunki skorzystamy z poniższego kodu:
springSecurityMock.encodePassword("password").returns("asd").times(1)Powyższy kod można rozbić na kilka członów:
- springSecurityMock.encodePassword("password") - jest to zdefiniowanie metody encodePassword, która spodziewa się podanego parametru
- returns("asd") - zdefiniowane wartości zwracanej dla metody z poprzedniego kroku
- .times(1) - nasze założenie testowe
Tak przygotowane założenie sprawdzamy za pomocą metody play:
gmock.play { sut.someMethodThatCallsEncodePassword() }
Poniżej prezentuję całą metodę testową z wykorzystaniem Gmock:
@Test void shouldCallEncodePassowrd() {   def gmock = new GMockController()   sut.springSecurity = gmock.mock(SpringSecurityService)   sut.springSecurity.Powyższy kod wykona się poprawnie, gdy metoda someMethodThatCallsEncodePassword faktycznie zawoła metodę encodePassword z parametrem "password".
    encodePassword("password").returns("asd").times(1)   gmock.play { sut.someMethodThatCallsEncodePassword() } }
Gmock jest bardzo ciekawą biblioteką, ponieważ potrafi podmieniać także metody statyczne, bądź też metody na żywych obiektach (tzw. partial mock), jednakże o tym w następnych postach.
Brak komentarzy:
Prześlij komentarz