Brug af SpringJUnit4ClassRunner med Parameterized

1. Oversigt

I denne vejledning ser vi, hvordan vi kan parametrere en Spring-integrationstest implementeret i JUnit4 med en Parameteriseret JUnit testløber.

2. SpringJUnit4ClassRunner

SpringJUnit4ClassRunner er en implementering af JUnit4's ClassRunner at indlejrer forårets TestContextManager ind i en JUnit-test.

TestContextManager er indgangsstedet til foråret TestContext ramme og administrerer derfor adgangen til foråret ApplicationContext og afhængighedsinjektion i en JUnit-testklasse. Dermed, SpringJUnit4ClassRunner gør det muligt for udviklere at implementere integrationstests til Spring-komponenter som controllere og arkiver.

For eksempel kan vi implementere en integrationstest til vores RestController:

@RunWith (SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration (klasser = WebConfig.class) offentlig klasse RoleControllerIntegrationTest {@Autowired privat WebApplicationContext wac; private MockMvc mockMvc; privat statisk endelig String CONTENT_TYPE = "applikation / tekst; charset = ISO-8859-1"; @Før offentlig ugyldig opsætning () kaster undtagelse {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .build (); } @Test offentlig ugyldighed givenEmployeeNameJohnWhenInvokeRoleThenReturnAdmin () kaster undtagelse {this.mockMvc.perform (MockMvcRequestBuilders .get ("/ role / John")) .andDo (print ()) .andExpect (MockMvcResultMatchers.). andExpect (MockMvcResultMatchers.content (). contentType (CONTENT_TYPE)). andExpect (MockMvcResultMatchers.content (). string ("ADMIN")); }}

Som det kan ses af testen, vores Controller accepterer et brugernavn som en sti-parameter og returnerer brugerrollen i overensstemmelse hermed.

Nu, For at teste denne REST-tjeneste med et andet brugernavn / rollekombination er vi nødt til at implementere en ny test:

@Test offentligt ugyldigt givenEmployeeNameDoeWhenInvokeRoleThenReturnEmployee () kaster undtagelse {this.mockMvc.perform (MockMvcRequestBuilders .get ("/ role / Doe")) .andDo (print ()) .andExpect (MockMvcResultMatchers.). (MockMvcResultMatchers.content (). ContentType (CONTENT_TYPE)). Og Expect (MockMvcResultMatchers.content (). Streng ("MEDARBEJDER")); }

Det her kan hurtigt komme ud af hånden for tjenester, hvor et stort antal inputkombinationer er mulige.

For at undgå denne form for gentagelse i vores testklasser, lad os se, hvordan du bruger Parameteriseret til implementering af JUnit-tests, der accepterer flere input.

3. Brug Parameteriseret

3.1. Definition af parametre

Parameteriseret er en brugerdefineret JUnit-testløber, der giver os mulighed for at skrive en enkelt testcase og få den til at køre mod flere inputparametre:

@RunWith (Parameterized.class) @WebAppConfiguration @ContextConfiguration (klasser = WebConfig.class) offentlig klasse RoleControllerParameterizedIntegrationTest {@Parameter (værdi = 0) offentlig Strengnavn; @Parameter (værdi = 1) offentlig String-rolle; @Parameters offentlige statiske indsamlingsdata () {Samlingsparametre = ny ArrayList (); params.add (nyt objekt [] {"John", "ADMIN"}); params.add (nyt objekt [] {"Doe", "MEDARBEJDER"}); returparametre; } // ...}

Som vist ovenfor brugte vi @Parameters kommentar for at forberede de inputparametre, der skal injiceres i JUnit-testen. Vi leverede også kortlægningen af ​​disse værdier i @Parameter felter navn og rolle.

Men nu har vi et andet problem at løse - JUnit tillader ikke flere løbere i en JUnit-testklasse. Det betyder vi kan ikke drage fordel af SpringJUnit4ClassRunner at integrere TestContextManagerind i vores testklasse. Vi bliver nødt til at finde en anden måde at integrere på TestContextManager.

Heldigvis giver Spring et par muligheder for at opnå dette. Vi diskuterer disse i de følgende afsnit.

3.2. Initialisering af TestContextManager Manuelt

Den første mulighed er ret enkel, da Spring giver os mulighed for at initialisere TestContextManager manuelt:

@RunWith (Parameterized.class) @WebAppConfiguration @ContextConfiguration (klasser = WebConfig.class) offentlig klasse RoleControllerParameterizedIntegrationTest {@Autowired privat WebApplicationContext wac; private MockMvc mockMvc; privat TestContextManager testContextManager; @Før offentlig ugyldig opsætning () kaster undtagelse {this.testContextManager = ny TestContextManager (getClass ()); this.testContextManager.prepareTestInstance (dette); this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .build (); } // ...}

Især i dette eksempel brugte vi Parameteriseret løber i stedet for SpringJUnit4ClassRunner. Derefter initialiserede vi TestContextManager i Opsætning() metode.

Nu kan vi implementere vores parametriserede JUnit-test:

@Test offentlig ugyldighed givenEmployeeNameWhenInvokeRoleThenReturnRole () kaster undtagelse {this.mockMvc.perform (MockMvcRequestBuilders .get ("/ role /" + name)) .andDo (print ()). Og Expect (MockMvcResultMatchers.status ().). andExpect (MockMvcResultMatchers.content (). contentType (CONTENT_TYPE)). andExpect (MockMvcResultMatchers.content (). streng (rolle)); }

JUnit udfører denne testsag to gange - en gang for hvert sæt indgange, vi definerede ved hjælp af @Parameters kommentar.

3.3. SpringClassRule og SpringMethodRule

Generelt, det anbefales ikke at initialisere TestContextManager manuelt. I stedet anbefaler Spring at bruge SpringClassRule og SpringMethodRule.

SpringClassRule implementerer JUnit's Testregel - en alternativ måde at skrive testsager på. Testregel kan bruges til at erstatte de opsætnings- og oprydningsoperationer, der tidligere var udført med @Før, @BeforeClass, @After, og @Efter skole metoder.

SpringClassRule indlejrer klassefunktionalitet af TestContextManager i en JUnit testklasse. Det initialiserer TestContextManager og påberåber sig opsætningen og oprydningen af ​​foråret TestContext. Derfor giver det afhængighedsindsprøjtning og adgang til ApplicationContext.

I tillæg til SpringClassRule, skal vi også bruge SpringMethodRule. som giver instansniveau og metodeniveau-funktionalitet til TestContextManager.

SpringMethodRule er ansvarlig for forberedelsen af ​​testmetoderne. Det kontrollerer også for testsager, der er markeret til at springe over, og forhindrer dem i at køre.

Lad os se, hvordan vi bruger denne tilgang i vores testklasse:

@RunWith (Parameterized.class) @WebAppConfiguration @ContextConfiguration (classes = WebConfig.class) public class RoleControllerParameterizedClassRuleIntegrationTest {@ClassRule public static final SpringClassRule scr = new SpringClassRule (); @Rule offentlig endelig SpringMethodRule smr = ny SpringMethodRule (); @Før offentlig ugyldig opsætning () kaster undtagelse {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .build (); } // ...}

4. Konklusion

I denne artikel diskuterede vi to måder at implementere Spring integrationstests ved hjælp af Parameteriseret testløber i stedet for SpringJUnit4ClassRunner. Vi så, hvordan man initialiserede TestContextManager manuelt, og vi så et eksempel ved hjælp af SpringClassRule med SpringMethodRule, den fremgangsmåde, der anbefales af foråret.

Selvom vi kun diskuterede Parameteriseret løber i denne artikel, vi kan faktisk bruge en af ​​disse tilgange med enhver JUnit-løber at skrive Spring Integration Test.

Som sædvanlig er al eksempelkoden tilgængelig på GitHub.