Formålet med en enhetstest er å identifisere feilene i en applikasjon så fort du kan. Selv om flere kanaler kan føre deg til samme mål, bør du sikte på å bruke den mest effektive ruten.
En JUnit-testpakke kan ha flere testklasser som trenger de samme dataene, men du kan ikke gjenbruke testdata. I tidligere versjoner av JUnit var en god tilnærming å lage en verktøymetode, og deretter kalle den metoden hver gang en testklasse trengte dataene sine.
JUnit 5 gir en mer effektiv tilnærming til dette problemet: avhengighetsinjeksjon (DI).
Hva er avhengighetsinjeksjon?
DI er et designmønster der et objekt leverer avhengighetene til et annet objekt. Når du bygger en Java-applikasjon, kan det hende du har en klasse som er avhengig av et objekt som en annen klasse lager for å utføre sin funksjon.
Før avhengighetsinjeksjon, for å bruke et objekt fra en annen klasse, må du opprette en ny forekomst av det objektet i klassen som avhenger av det. Så hvis du hadde flere klasser som er avhengige av det samme objektet, må du opprette flere forekomster av det innenfor de avhengige klassene.
DI lar deg bruke et objekt i en avhengig klasse, uten å opprette en ny forekomst av det i den klassen.
Avhengighetsinjeksjon i JUnit 5
JUnit 5 lar deg injisere avhengigheter i både testmetoder og konstruktører. Dette er viktig ettersom de tidligere versjonene av rammeverket ikke tillot testmetoder eller konstruktører å ha parametere.
JUnit 5 lar deg injisere så mange parametere du vil. Den eneste haken er at ParameterResolver API må være i stand til å løse hver parameter ved kjøretid. JUnit har for tiden tre innebygde parameteroppløsere som den bruker automatisk. For å bruke en annen resolver, må du registrere den eksplisitt ved å bruke @ExtendWith-kommentaren.
Injeksjonsavhengigheter i JUnit
Dette eksempelprogrammet bruker en av JUnits innebygde parametere (TestInfoParameterResolver), for å demonstrere hvordan du kan injisere en avhengighet i en JUnit 5 test. TestInfoParameterResolver løser objekter som tilhører TestInfo-grensesnittet. Så JUnit 5 vil levere en forekomst av TestInfo-grensesnittet til enhver metode eller konstruktør som bruker den.
importstatisk org.junit.jupiter.api. Påstander.*;
import org.junit.jupiter.api. Visningsnavn;
import org.junit.jupiter.api. Test;
import org.junit.jupiter.api. TestInfo;klasseInfoTestInterfaceTest{
// Injiserer et testInfo-objekt i InfoTestInterfaceTest-konstruktøren
InfoTestInterfaceTest (TestInfo testInfo) {
assertEquals("InfoTestInterfaceTest", testInfo.getDisplayName());
}// Injiserer et testInfo-objekt i metoder
@Test
tomromtestMethodName(TestInfo testInfo){
assertEquals("testMethodName (TestInfo)", testInfo.getDisplayName());
}
@Test
@Visningsnavn("metoden som bruker @Visningsnavn merknad")
tomromtestMetodeNavnTo(TestInfo testInfo){
assertEquals("metoden som bruker @Visningsnavn annotation", testInfo.getDisplayName());
}
}
JUnit-testen ovenfor viser hvordan man injiserer et objekt i en konstruktør og to metoder. De JUnit TestInfo grensesnittet har fire metoder som du kan bruke med objektet.
Metoden getDisplayName() er den mest nyttige. Den returnerer visningsnavnet til gjeldende testmetode eller konstruktør. Som standard er dette navnet basert på klassen. Men hvis du bruker @DisplayName-kommentaren, vil getDisplayName()-metoden returnere den teksten i stedet.
Testklassen ovenfor genererer følgende testrapport:
Bruk DI i @Before og @After Methods
Det er fire andre typer JUnit-annoterte metoder som støtter avhengigheter. Dette er merknadene @BeforeAll, @BeforeEach, @AfterAll og @AfterEach. I likhet med @Test-metoden, er alt du trenger å gjøre å sende et objekt til en av før- eller ettermetodene som en parameter, og du er i gang.
@Før- og @Etter-kommentarene er viktige, siden de også hjelper deg med å utvikle mer effektiv testkode. Å ha muligheten til også å injisere avhengigheter i disse metodene vil forbedre testkoden ytterligere.