Mockito – ja testataan ihan mitä vain isolaatiossa

Olen joskus aiemmin kirjaillut juttuja siitä miten esim. EJB komponentteja voidaan yksikkötestata – ja käytellyt välineenä EasyMockia. Testaus isolaatiossa, eristyksissä muusta on yksi tavoiteltava asia koska näin tehdyt testit voidaan ajaa salamannopeasti ja jatkuvasti, saaden palautetta muutoksista koko ajan.

Mockito-JUnit

Sanoinko testit? Köhköh, tarkoitin tiestysti speksit. Isolaatiotestit mahdollistavat TDD ja BDD disipliinien soveltamisen haltuessaan, tai itseni suosima Spec-While-Writing tapa joka on oikeastaan ihan samaa kuin em mutta rennommin rantein. Fanaattiset isolaatiotestithän eivät nimenomaan ole testeinä kovinkaan hyviä usein, mutta spekseinä ne ovat aivan verrattomia, ja monimutkaiselle logiikalle lähes ilmaiseksi sivuvaikutuksena syntyvät testitkään eivät ole ihan huono asia.

Sanoinko ilmaiseksi? Hups. Kyllähän testien kirjoittamiseen aikaa kuluu, etenkin jos niitä säveltää etupainotteisesti ennen koodipyrähdyksiä. Etenkin isolaation saavuttaminen on aika ajoin hankalaa. Viime aikoina olen löytänyt uutta apua tälle saralle: Kuten otsikko jo spoilasi, Mockito framework on varsin kiva, etenkin Spring Bootin kanssa. Vastaavaan tapaan Javascript-puolella käyttelen nykyään Jasmine mockeja, mutta tämä ei ole artikkeli niistä vaan Mockitosta. Tässä siis vähän maistiaisia siitä miltä maistuu yksikkötestaus mockitolla ja mitä hyöytyä siitä saa.

Mockito testi voi olla tavallinen JUnit tai TestNG testi, eli aloitellaan tähän tapaan:

public class UserResourceTest {

  @Test
  public void changePasswordShouldSucceedWithValidParameters() 
    throws Exception {
      fail("Not implemented yet");
  }

}

Testatessa on tietysti mukavaa olla se mitä testataan. Perinteisesti sen voi vaikka instansioida nimellä sut – system under test, Mockitolla homma hoituu näin:

@InjectMocks
private UserResource sut;

Jotta tuo tekee jotain on tietysti syytä ajaa tämä Mockiton kera. Lisätäänpä siis testiluokan alkuun:

@RunWith(MockitoJUnitRunner.class)

Nyt tapahtuu jo jotain. Tässä testattavassa luokassa on kuitenkin paljon riippuvuuksia, jäsenmuuttujissa on yhtä ja toista jota Spring injektoi ajon aikana, mutta jotka aiheuttavat nullpointer exceptioneitä ellei niitä ole alustettu. Olen joskus injektoinut näitä riippuvuuksia reflectionin avulla, joskus setXXX-metodeita tekemällä. Mockitolla homma sujuu kokonaisuudessaan näin:

@RunWith(MockitoJUnitRunner.class)
public class UserResourceTest {

    @Mock
    private Utils utils;

    @Mock
    private UserDetailsService userDetailsServiceMock;

    @InjectMocks
    private UserResource sut;

Eli, kun alan kirjoittelemaan omaa testiäni, kaikki kolme edellämainittua on instansioitu Mockiton toimesta, mock objekteille on mock toteutukset, jotka esim. palauttavat null/eivät tee mitään. Ja mikä parasta, mock objektit on injektoitu sut objektin sisään, privaatteihin jäsenmuuttuja-kenttiin. Ensin yritetään samalla tyypillä, sitten samalla nimellä.

Mockiton oma dokumentaatio InjectMocks-metodista sanoo näin:

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won’t report failure; i.e. you will have to provide dependencies yourself.

Eli tarkkana tämän kanssa.

Mitä muuta hienoa? No Mockitossa on verrattain helppoa opettaa mockit palauttamaan sopivia arvoja, esim:

UserEntity currentUser = new UserEntity();
UserAuthentication userAuthentication = new UserAuthentication(currentUser);
when(utils.getAuthentication()).thenReturn(userAuthentication);

Ja sitten vain paukuttamaan omaa suttia, joka taas kutsuu tuota utils.getAuthentication() metodia. Jos haluat tarkistaa, kutsuiko, sen voi tarkistaa verify-kutsulla:

verify(utils).getAuthentication();

Eli, Mockito vaikuttaisi hyvältä. Pääidea on tuoda testauksen hintaa alas, ja näin saada siitä yhtä luontevaa kuin hengittäminen. Tai luontevampaa.

 

Advertisements

2 thoughts on “Mockito – ja testataan ihan mitä vain isolaatiossa

    • Yksi hyöty blogin kirjoittamisesta on että saa aina välillä kuulla uusia ajatuksia. Spockista olen joskus kuullut, mutten koskaan käyttänyt. Se menee siis testiin jossain vaiheessa, kuulostaa hyvältä 😉

      Groovy on rakastettava kieli, etenkin testipuolella.

Vastaa

Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:

WordPress.com-logo

Olet kommentoimassa WordPress.com -tilin nimissä. Log Out / Muuta )

Twitter-kuva

Olet kommentoimassa Twitter -tilin nimissä. Log Out / Muuta )

Facebook-kuva

Olet kommentoimassa Facebook -tilin nimissä. Log Out / Muuta )

Google+ photo

Olet kommentoimassa Google+ -tilin nimissä. Log Out / Muuta )

Muodostetaan yhteyttä palveluun %s