Veiledning til JUnit 4-regler

1. Oversikt

I denne opplæringen skal vi ta en titt på Regelfunksjonen som tilbys av JUnit 4-biblioteket.

Vi begynner med å introdusere JUnit Rules Model før vi går gjennom de viktigste grunnreglene gitt av distribusjonen. I tillegg vil vi også se hvordan vi skriver og bruker vår egen tilpassede JUnit-regel.

For å lære mer om testing med JUnit, sjekk ut den omfattende JUnit-serien.

Merk at hvis du bruker JUnit 5, har reglene blitt erstattet av utvidelsesmodellen.

2. Introduksjon til JUnit 4-regler

JUnit 4-reglene gir en fleksibel mekanisme for å forbedre testene ved å kjøre litt kode rundt en testutførelse. På en eller annen måte ligner det på å ha @Før og @Etter kommentarer i testklassen vår.

La oss forestille oss at vi ønsket å koble til en ekstern ressurs, for eksempel en database under testoppsettet, og deretter lukke forbindelsen etter at testen er ferdig. Hvis vi vil bruke databasen i flere tester, vil vi ende opp med å duplisere koden i hver test.

Ved å bruke en regel kan vi ha alt isolert på ett sted og gjenbruke koden enkelt fra flere testklasser.

3. Bruke JUnit 4-regler

Så hvordan kan vi bruke regler? Vi kan bruke JUnit 4-regler ved å følge disse enkle trinnene:

  • Legg til en offentlig feltet til testklassen vår og sikre at typen av dette feltet er en undertype av org.junit.rules.TestRule grensesnitt
  • Kommenter feltet med @Regel kommentar

I neste avsnitt ser vi hvilke prosjektavhengigheter vi trenger for å komme i gang.

4. Maven Avhengigheter

La oss først legge til prosjektavhengighetene vi trenger for eksemplene våre. Vi trenger bare hovedbiblioteket JUnit 4:

 junit junit 4.12 

Som alltid kan vi få den nyeste versjonen fra Maven Central.

5. Regler gitt i distribusjonen

Selvfølgelig, JUnit gir en rekke nyttige, forhåndsdefinerte regler som en del av biblioteket. Vi finner alle disse reglene i org.junit.regler pakke.

I denne delen ser vi noen eksempler på hvordan du bruker dem.

5.1. De Midlertidig mappe Regel

Når vi tester, trenger vi ofte tilgang til en midlertidig fil eller mappe. Å administrere opprettelse og sletting av disse filene kan imidlertid være tungvint. Bruker Midlertidig mappe regel, kan vi administrere opprettelsen av filer og mapper som skal slettes når testmetoden avsluttes:

@Rule public TemporaryFolder tmpFolder = ny TemporaryFolder (); @Test offentlig ugyldighet givenTempFolderRule_whenNewFile_thenFileIsCreated () kaster IOException {File testFile = tmpFolder.newFile ("test-file.txt"); assertTrue ("Filen burde ha blitt opprettet:", testFile.isFile ()); assertEquals ("Temp-mappen og testfilen skal samsvare med:", tmpFolder.getRoot (), testFile.getParentFile ()); }

Som vi kan se, definerer vi først Midlertidig mappe regel tmpFolder. Deretter oppretter testmetoden vår fil kalt test-file.txt i den midlertidige mappen. Vi sjekker deretter at filen er opprettet og eksisterer der den skal. Virkelig hyggelig og enkelt!

Når testen er ferdig, bør den midlertidige mappen og filen slettes. Denne regelen kontrollerer imidlertid ikke om slettingen er vellykket.

Det er også noen andre interessante metoder som er verdt å nevne i denne klassen:

  • newFile ()

    Hvis vi ikke gir noe filnavn, oppretter denne metoden en tilfeldig navngitt ny fil.

  • newFolder (String ... folderNames)

    For å lage rekursivt dype midlertidige mapper, kan vi bruke denne metoden.

  • ny mappe()

    Likeledes, den ny mappe() metoden oppretter en tilfeldig navngitt ny mappe.

Et fint tillegg verdt å nevne er at fra og med versjon 4.13, Midlertidig mappe regel tillater bekreftelse av slettede ressurser:

@Rule public TemporaryFolder folder = TemporaryFolder.builder (). AssureDeletion (). Build ();

Hvis en ressurs ikke kan slettes, mislykkes testen med en Påstand Feil.

Til slutt, i JUnit 5, kan vi oppnå den samme funksjonaliteten ved hjelp av Temporary Directory-utvidelsen.

5.2. De ExpectedException Regel

Som navnet antyder, vi kan bruke ExpectedException regel for å bekrefte at noen koder gir et forventet unntak:

@Rule public final ExpectedException kastet = ExpectedException.none (); @Test offentlig ugyldighet gittIllegalArgument_whenExceptionThrown_MessageAndCauseMatches () {throw.expect (IllegalArgumentException.class); kastet.expectCause (isA (NullPointerException.class)); throw.expectMessage ("Dette er ulovlig"); kaste nye IllegalArgumentException ("Dette er ulovlig", nytt NullPointerException ()); }

Som vi kan se i eksemplet ovenfor, erklærer vi først at ExpectedException regel. Så i vår test hevder vi at en IllegalArgumentException blir kastet.

Ved å bruke denne regelen kan vi også verifisere noen andre egenskaper for unntaket, for eksempel meldingen og årsaken.

For en grundig guide for å teste unntak med JUnit, sjekk ut vår gode guide om hvordan du kan hevde et unntak.

5.3. De Testnavn Regel

Enkelt sagt, den Testnavn regel gir det gjeldende testnavnet i en gitt testmetode:

@Rule public TestName name = new TestName (); @Test offentlig ugyldig gittAddition_whenPrintingTestName_thenTestNameIsDisplayed () {LOG.info ("Utfører: {}", name.getMethodName ()); assertEquals ("givenAddition_whenPrintingTestName_thenTestNameIsDisplayed", name.getMethodName ()); }

I dette trivielle eksemplet, når vi kjører enhetstesten, bør vi se testnavnet i utgangen:

INFO c.baeldung.rules.JUnitRulesUnitTest - Utfører: givenAddition_whenPrintingTestName_thenTestNameIsDisplayed

5.4. De Pause Regel

I dette neste eksemplet ser vi på Pause regel. Denne regelen gir et nyttig alternativ til å bruke tidsavbruddsparameteren på en individuell testkommentar.

La oss nå se hvordan vi bruker denne regelen til å sette en global tidsavbrudd på alle testmetodene i testklassen vår:

@Rule public Timeout globalTimeout = Timeout.seconds (10); @Test offentlig ugyldig gittLongRunningTest_whenTimout_thenTestFails () kaster InterruptedException {TimeUnit.SECONDS.sleep (20); }

I det trivielle eksemplet ovenfor, vi definerer først et globalt tidsavbrudd for alle testmetoder på 10 sekunder. Deretter definerer vi bevisst en test som tar lengre tid enn 10 sekunder.

Når vi kjører denne testen, bør vi se en testfeil:

org.junit.runners.model.TestTimedOutException: testen ble avbrutt etter 10 sekunder ...

5.5. De ErrorCollector Regel

Neste gang skal vi ta en titt på ErrorCollector regel. Denne regelen gjør at utførelsen av en test kan fortsette etter at det første problemet er funnet.

La oss se hvordan vi kan bruke denne regelen til å samle alle feilene og rapportere dem på en gang når testen avsluttes:

@Rule public final ErrorCollector errorCollector = ny ErrorCollector (); @Test public void givenMultipleErrors_whenTestRuns_thenCollectorReportsErrors () {errorCollector.addError (new Throwable ("Det første gikk galt!")); errorCollector.addError (ny Throwable ("En annen ting gikk galt!"); errorCollector.checkThat ("Hello World", ikke (inneholderString ("FEIL!"))); }

I eksemplet ovenfor legger vi to feil til samleren. Når vi kjører testen, fortsetter utførelsen, men testen mislykkes til slutt.

I utgangen vil vi se begge feilene rapportert:

java.lang.Trowable: Det første gikk galt! ... java.lang.Trowable: En annen ting gikk galt!

5.6. De Verifier Regel

De Verifier regelen er en abstrakt basisklasse som vi kan bruke når vi ønsker å verifisere ytterligere atferd fra testene våre. Faktisk, den ErrorCollector regelen vi så i den siste delen utvider denne klassen.

La oss nå se på et trivielt eksempel på å definere vår egen verifier:

private List messageLog = new ArrayList (); @Rule public Verifier verifier = new Verifier () {@Override public void verify () {assertFalse ("Message Log is not Empty!", MessageLog.isEmpty ()); }}; 

Her definerer vi en ny Verifier og overstyre bekrefte() metode for å legge til litt ekstra bekreftelseslogikk. I dette enkle eksemplet sjekker vi bare for å se at meldingsloggen i eksemplet vårt ikke er tomt.

Nå, når vi kjører enhetstesten og legger til en melding, bør vi se at bekrefteren vår er brukt:

@Test offentlig ugyldig gittNewMessage_whenVerified_thenMessageLogNotEmpty () {// ... messageLog.add ("Det er en ny melding!"); }

5.7. De DisableOnDebug Regel

Noen ganger kan det være lurt å deaktivere en regel når vi feilsøker. For eksempel er det ofte ønskelig å deaktivere a Pause regelen når vi feilsøker, for å unngå at testtidsavbruddet mislykkes før vi har fått tid til å feilsøke det riktig.

De DisableOnDebug Regel gjør nettopp dette og lar oss merke visse regler som skal deaktiveres når vi feilsøker:

@Rule public DisableOnDebug disableTimeout = ny DisableOnDebug (Timeout.seconds (30));

I eksemplet ovenfor kan vi se at for å bruke denne regelen, vi overfører bare regelen vi vil deaktivere til konstruktøren.

Den viktigste fordelen med denne regelen er at vi kan deaktivere regler uten å gjøre noen endringer i testklassene våre under feilsøking.

5.8. De Ekstern ressurs Regel

Når vi skriver integrasjonstester, vil vi vanligvis sette opp en ekstern ressurs før en test og rive den ned etterpå. Heldigvis gir JUnit nok en praktisk basisklasse for dette.

Vi kan utvide den abstrakte klassen Ekstern ressurs å sette opp en ekstern ressurs før en test, for eksempel en fil eller en databaseforbindelse. Faktisk, den Midlertidig mappe regelen vi så tidligere strekker seg Ekstern ressurs.

La oss se raskt på hvordan vi kan utvide denne klassen:

@Rule offentlig slutt ExternalResource externalResource = ny ExternalResource () {@Override beskyttet tomrom før () kaster Throwable {// kode for å sette opp en spesifikk ekstern ressurs. }; @ Override beskyttet tomrom etter () {// kode for å rive ned den eksterne ressursen}; };

I dette eksemplet, når vi definerer en ekstern ressurs, trenger vi bare å overstyre før() metode og etter() metode for å sette opp og rive ned vår eksterne ressurs.

6. Bruk av klasseregler

Inntil nå har alle eksemplene vi har sett på, anvendt på enkel test case-metoder. Noen ganger vil vi imidlertid kanskje bruke en regel på testklassenivå. Vi kan oppnå dette ved å bruke @ClassRule kommentar.

Denne kommentaren fungerer veldig likt @Regel men bryter en regel rundt en hel test - Hovedforskjellen er at feltet vi bruker for klasseregelen vår, må være statisk:

@ClassRule offentlig statisk TemporaryFolder globalFolder = ny TemporaryFolder ();

7. Definere en tilpasset JUnit-regel

Som vi har sett, gir JUnit 4 en rekke nyttige regler ut av esken. Selvfølgelig kan vi definere våre egne tilpassede regler. For å skrive en tilpasset regel, må vi implementere TestRule grensesnitt.

La oss se på et eksempel på å definere en egendefinert testmetode navneloggregel:

offentlig klasse TestMethodNameLogger implementerer TestRule {private static final Logger LOG = LoggerFactory.getLogger (TestMethodNameLogger.class); @Override public Erklæring gjelder (Uttalelsesbase, Beskrivelse av beskrivelse) {logInfo ("Før test", beskrivelse); prøv {return new Statement () {@Override public void evaluere () kaster Throwable {base.evaluate (); }}; } til slutt {logInfo ("Etter test", beskrivelse); }} privat tomrom logInfo (String msg, Beskrivelse av beskrivelse) {LOG.info (msg + description.getMethodName ()); }}

Som vi kan se, er TestRule grensesnittet inneholder en metode som kalles gjelder (uttalelse, beskrivelse) som vi må overstyre for å returnere en forekomst av Uttalelse. Uttalelsen representerer våre tester innen JUnit-kjøretiden. Når vi kaller evaluere() metoden, utfører dette testen vår.

I dette eksemplet logger vi en før og etter melding og inkluderer fra Beskrivelse motsette seg metodens navn på den enkelte testen.

8. Bruke regelkjeder

I denne siste delen vil vi se på hvordan vi kan bestille flere testregler ved hjelp av RuleChain regel:

@Rule public RuleChain chain = RuleChain.outerRule (new MessageLogger ("First rule")) .around (new MessageLogger ("Second rule")) .around (new MessageLogger ("Third rule"));

I eksemplet ovenfor oppretter vi en kjede med tre regler som bare skriver ut meldingen som sendes til hver MessageLogger konstruktør.

Når vi kjører testen, ser vi hvordan kjeden blir brukt i rekkefølge:

Start: Første regel Start: Andre regel Start: Tredje regel Ferdig: Tredje regel Ferdig: Andre regel Ferdig: Første regel

9. Konklusjon

For å oppsummere har vi i denne veiledningen utforsket JUnit 4-reglene i detalj.

Først begynte vi med å forklare hva reglene er og hvordan vi kan bruke dem. Deretter tok vi en grundig titt på reglene som kommer som en del av JUnit-distribusjonen.

Til slutt så vi på hvordan vi kan definere vår egen tilpassede regel og hvordan vi kan kjede regler sammen.

Som alltid er hele kildekoden til artikkelen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found