Pavasario MVC yra viena iš populiariausių „Java“ struktūrų kuriant įmonės „Java“ programas, ir ji labai tinka testavimui. Pagal savo planą „Spring MVC“ skatina atskirti rūpesčius ir skatina koduoti sąsajas. Dėl šių savybių kartu su pavasariu įdiegta priklausomybės injekcija pavasario programas galima labai išbandyti.
Ši pamoka yra antra mano įvado į įrenginių testavimą naudojant „JUnit 5“ pusę. Aš jums parodysiu, kaip integruoti „JUnit 5“ su „Spring“, tada supažindinsiu jus su trim įrankiais, kuriais galėsite išbandyti „Spring MVC“ valdiklius, paslaugas ir saugyklas.
atsisiųsti Gauti kodą Atsisiųskite šioje pamokoje naudojamų programų, pavyzdžiui, šaltinio kodą. Stevenas Hainesas sukūrė „JavaWorld“.JUnit 5 integravimas su 5 spyruokle
Šioje pamokoje mes naudojame „Maven“ ir „Spring Boot“, todėl pirmas dalykas, kurį turime padaryti, yra pridėti „JUnit 5“ priklausomybę prie „Maven POM“ failo:
org.junit.jupiter junit-jupiter 5.6.0 testas
Kaip ir tai darėme 1 dalyje, šiame pavyzdyje naudosime „Mockito“. Taigi reikės pridėti „JUnit 5 Mockito“ biblioteką:
org.mockito mockito-junit-jupiter 3.2.4 testas
@ExtendWith ir „SpringExtension“ klasė
5 JUnitas apibrėžia plėtinio sąsaja, per kurią klasės gali integruotis į „JUnit“ testus įvairiuose vykdymo gyvavimo ciklo etapuose. Galime įgalinti plėtinius pridėdami @ExtendWith
anotacija mūsų bandymų klasėms ir nurodoma įkeliamos pratęsimo klasė. Tada plėtinys gali įdiegti įvairias atgalinio ryšio sąsajas, kurios bus naudojamos per visą bandymo gyvavimo ciklą: prieš pradedant visus bandymus, prieš kiekvieną bandymą, po kiekvieno bandymo ir po to, kai visi bandymai buvo atlikti.
Pavasaris apibrėžia a Pavasario pratęsimas
klasė, užsiprenumeravusi „JUnit 5“ gyvavimo ciklo pranešimus, norėdama sukurti ir palaikyti „bandomąjį kontekstą“. Primename, kad „Spring“ programos kontekste yra visos pavasario pupelės programoje ir kad ji atlieka priklausomybės injekciją, kad sujungtų programą ir jos priklausomybes. „Spring“ naudoja „JUnit 5“ plėtinio modelį, kad išlaikytų testo taikymo kontekstą, todėl rašymo vieneto testai su „Spring“ yra aiškūs.
Pridėję JUnit 5 biblioteką prie savo „Maven POM“ failo, galime naudoti SpringExtension.class
pratęsti mūsų „JUnit 5“ testų klases:
@ExtendWith (SpringExtension.class) klasės „MyTests“ {// ...}
Šiuo atveju pavyzdys yra „Spring Boot“ programa. Laimei @SpringBootTest
anotacijoje jau yra @ExtendWith (SpringExtension.class)
anotacija, todėl mums tereikia įtraukti @SpringBootTest
.
Pridedant „Mockito“ priklausomybę
Norėdami tinkamai išbandyti kiekvieną komponentą atskirai ir imituoti skirtingus scenarijus, norėsime sukurti bandomąjį kiekvienos klasės priklausomybės įgyvendinimą. Čia yra „Mockito“. Įtraukite šią priklausomybę į savo POM failą, kad pridėtumėte „Mockito“ palaikymą:
org.mockito mockito-junit-jupiter 3.2.4 testas
Integravę „JUnit 5“ ir „Mockito“ į savo „Spring“ programą, galite pasinaudoti „Mockito“ naudodami savo testo klasėje paprasčiausiai apibrėždami pavasarinę pupelę (pvz., Paslaugą ar saugyklą) naudodami @MockBean
anotacija. Štai mūsų pavyzdys:
@SpringBootTest viešosios klasės „WidgetServiceTest“ {/ ** * „Autowire“ paslaugoje, kurią norime išbandyti * / @Autowired private WidgetService service; / ** * Sukurti WidgetRepository * / @MockBean private WidgetRepository talpyklą; ...}
Šiame pavyzdyje mes kuriame maketą „WidgetRepository“
mūsų viduje „WidgetServiceTest“
klasė. Kai Pavasaris tai pamatys, jis automatiškai sujungs mus „WidgetService“
kad galėtume sukurti skirtingus scenarijus savo bandymų metoduose. Kiekvienas bandymo metodas sukonfigūruos „WidgetRepository“
, pavyzdžiui, grąžindami prašomą Valdiklis
arba grąžinant Pasirenkama. Tuščia ()
užklausai, kurios duomenys nerandami. Likusią šios mokymo dalies dalį praleisime ieškodami įvairių būdų, kaip sukonfigūruoti šias maketuotas pupeles.
Pavasario MVC pavyzdinė programa
Norėdami parašyti pavasarinius vieneto testus, mums reikia programos, kuriai prieš juos parašyti. Laimei, galime naudoti mano pavyzdinę programą Pavasario serija pamoka "Pavasario sistemos 5 įvaldymas, 1 dalis: pavasario MVC". Aš naudoju tos mokymo programos pavyzdinę programą kaip pagrindinę programą. Pakeičiau ją naudodamas stipresnę REST API, kad turėtume išbandyti dar keletą dalykų.
Programos pavyzdys yra „Spring MVC“ žiniatinklio programa su REST valdikliu, paslaugų lygiu ir saugykla, kuri naudoja „Spring Data JPA“, kad išlaikytų „valdiklius“ į H2 atminties duomenų bazę ir iš jos. 1 paveiksle pateikiama apžvalga.

Kas yra valdiklis?
A Valdiklis
yra tik „daiktas“ su ID, pavadinimu, aprašymu ir versijos numeriu. Šiuo atveju mūsų valdikliui pridedamos JPA anotacijos, kad jis būtų apibrėžtas kaip subjektas. „WidgetRestController“
yra pavasario MVC valdiklis, kuris RESTful API kvietimus paverčia veiksmais, kuriuos reikia atlikti Valdikliai
. „WidgetService“
yra standartinė pavasario paslauga, apibrėžianti verslo funkcionalumą Valdikliai
. Galiausiai „WidgetRepository“
yra „Spring Data“ JPA sąsaja, kuriai „Spring“ sukurs įgyvendinimą vykdymo metu. Rašydami testus, mes peržiūrėsime kiekvienos klasės kodą kitose dalyse.
Padalinys išbando pavasario paslaugą
Pradėkime nuo peržiūros, kaip išbandyti pavasarįpaslaugą, nes tai yra lengviausias mūsų MVC programos komponentas. Šio skyriaus pavyzdžiai leis mums ištirti „JUnit 5“ integraciją su „Spring“ neįvedant jokių naujų testavimo komponentų ar bibliotekų, nors tai padarysime vėliau pamokoje.
Pirmiausia peržiūrėsime „WidgetService“
sąsaja ir „WidgetServiceImpl“
klasės, kurios rodomos atitinkamai 1 ir 2 sąrašuose.
Sąrašas 1. „Spring“ paslaugų sąsaja (WidgetService.java)
paketas com.geekcap.javaworld.spring5mvcexample.service; importuoti com.geekcap.javaworld.spring5mvcexample.model.Widget; importuoti java.util.List; importuoti java.util.Privaloma; viešoji sąsaja „WidgetService“ {Neprivaloma „findById“ (ilgas ID); Sąrašas findAll (); Valdiklio išsaugojimas (Valdiklio valdiklis); void deleteById (ilgas ID); }
2 sąrašas. Pavasario paslaugų diegimo klasė (WidgetServiceImpl.java)
paketas com.geekcap.javaworld.spring5mvcexample.service; importuoti com.geekcap.javaworld.spring5mvcexample.model.Widget; importuoti com.geekcap.javaworld.spring5mvcexample.repository.WidgetRepository; importuoti com.google.common.collect.Lists; importuoti org.springframework.stereotype.Service; importuoti java.util.ArrayList; importuoti java.util.List; importuoti java.util.Privaloma; @Service viešoji klasė „WidgetServiceImpl“ įgyvendina „WidgetService“ {privačią „WidgetRepository“ saugyklą; public WidgetServiceImpl (WidgetRepository repository) {this.repository = saugykla; } @Paisyti viešą Pasirenkamas „findById“ (ilgas ID) {return repository.findById (id); } @Paisyti viešąjį sąrašą findAll () {return Lists.newArrayList (repository.findAll ()); } @Paisyti viešą valdiklių išsaugojimą (valdiklių valdiklis) {// Padidinkite versijos numerį widget.setVersion (widget.getVersion () + 1); // Įrašykite valdiklį į saugyklą grąžinkite saugyklą.save (valdiklis); } @Paisyti viešą nieką deleteById (ilgas ID) {repository.deleteById (id); }}
„WidgetServiceImpl“
yra pavasario paslauga, anotuota @Service
anotacija, turinti a „WidgetRepository“
prijungtas prie jo per jo konstruktorių. „findById“ ()
, findAll ()
ir deleteById ()
metodai yra visi pagrindiniai metodai „WidgetRepository“
. Vienintelė verslo logika, kurią rasite, yra sutaupyti()
metodas, kuris padidina. versijos numerį Valdiklis
kai jis išsaugomas.
Testo klasė
Norėdami išbandyti šią klasę, turime sukurti ir sukonfigūruoti maketą „WidgetRepository“
, prijunkite jį prie „WidgetServiceImpl“
pavyzdžiui, ir tada prijunkite „WidgetServiceImpl“
į mūsų testų klasę. Laimei, tai kur kas lengviau, nei atrodo. 3 sąraše rodomas šaltinio kodas „WidgetServiceTest“
klasė.
3 sąrašas. Pavasario paslaugų testo klasė (WidgetServiceTest.java)
paketas com.geekcap.javaworld.spring5mvcexample.service; importuoti com.geekcap.javaworld.spring5mvcexample.model.Widget; importuoti com.geekcap.javaworld.spring5mvcexample.repository.WidgetRepository; importuoti org.junit.jupiter.api.Aertertions; importuoti org.junit.jupiter.api.DisplayName; importuoti org.junit.jupiter.api.Test; importuoti org.junit.jupiter.api.extension.ExtendWith; importuoti org.springframework.beans.factory.annotation.Autowired; importuoti org.springframework.boot.test.context.SpringBootTest; importuoti org.springframework.boot.test.mock.mockito.MockBean; importuoti org.springframework.test.context.junit.jupiter.SpringExtension; importuoti java.util.Arrays; importuoti java.util.List; importuoti java.util.Privaloma; importuoti statinį org.mockito.Mockito.doReturn; importuoti statinį org.mockito.ArgumentMatchers.any; @SpringBootTest viešosios klasės „WidgetServiceTest“ {/ ** * „Autowire“ paslaugoje, kurią norime išbandyti * / @Autowired private WidgetService service; / ** * Sukurti WidgetRepository * / @MockBean private WidgetRepository talpyklą; @Test @DisplayName ("Test findById Success") void testFindById () {// Nustatykite savo maketo saugyklą Valdiklio valdiklis = naujas valdiklis (1l, "Valdiklio pavadinimas", "Aprašymas", 1); doReturn (Pasirenkama. (valdikliui)). kai (saugykla) .findById (1l); // Vykdyti tarnybinį iškvietimą Pasirenkama returnWidget = service.findById (1l); // Tvirtinkite atsakymą Assertions.assertTrue (returnWidget.isPresent (), "Valdiklis nerastas"); „Assertions.assertSame“ (returnWidget.get (), valdiklis, „Grąžintas valdiklis nebuvo tas pats, kaip maketas“); } @Test @DisplayName („Test findById Not Found“) void testFindByIdNotFound () {// Nustatykite savo maketo repliką „doReturn“ („Optional.empty“ ()). Kai (saugykla). // Vykdyti tarnybinį iškvietimą Pasirenkama returnWidget = service.findById (1l); // Tvirtinkite atsakymą Assertions.assertFalse (returnWidget.isPresent (), "Valdiklio negalima rasti"); } @Test @DisplayName ("Test findAll") void testFindAll () {// Nustatykite savo maketo saugyklą Valdiklio valdiklis1 = naujas valdiklis (1l, "Valdiklio pavadinimas", "Aprašymas", 1); Valdiklio valdiklis2 = naujas valdiklis (2l, „2 valdiklio pavadinimas“, „2 aprašas“, 4); doReturn (Arrays.asList (widget1, widget2)). kai (saugykla) .findAll (); // Vykdykite paslaugų skambučių sąrašo valdiklius = service.findAll (); // Tvirtinkite atsakymą Assertions.assertEquals (2, widgets.size (), "findAll turėtų grąžinti 2 valdiklius"); } @Test @DisplayName ("Test save widget") void testSave () {// Nustatykite savo maketo saugyklą Valdiklių valdiklis = naujas valdiklis (1l, "Valdiklio pavadinimas", "Aprašas", 1); doReturn (valdiklis) .kada (saugykla) .saugoti (bet koks ()); // Vykdykite tarnybos skambutį Widget ReturnWidget = service.save (valdiklis); // Tvirtinkite atsakymą Assertions.assertNotNull (returnWidget, "Išsaugotas valdiklis neturėtų būti nulinis"); Assertions.assertEquals (2, returnWidget.getVersion (), "Versija turėtų būti didinama"); }}
„WidgetServiceTest“
klasė yra pažymėta @SpringBootTest
anotacija, kuria nuskaitoma CLASSPATH
visoms „Spring“ konfigūracijos klasėms ir pupelėms bei sukuria „Spring“ taikymo kontekstą bandymų klasei. Prisimink tai „WidgetServiceTest“
taip pat netiesiogiai apima @ExtendWith (SpringExtension.class)
anotacija per @SpringBootTest
anotacija, integruojanti testo klasę su „JUnit 5“.
Testo klasėje taip pat naudojami „Spring“ @Autowired
anotacija automatiniam prisijungimui a „WidgetService“
norint išbandyti, ir jis naudoja „Mockito“ @MockBean
anotacija sukurti pašaipą „WidgetRepository“
. Šiuo metu turime pašaipą „WidgetRepository“
kad mes galime sukonfigūruoti, ir tikras „WidgetService“
su pašaipa „WidgetRepository“
laidas į jį.
„Pavasario“ paslaugos išbandymas
Pirmasis bandymo metodas, testFindById ()
, vykdo „WidgetService“
's „findById“ ()
metodas, kuris turėtų grąžinti Neprivaloma
kuriame yra a Valdiklis
. Mes pradedame kurti Valdiklis
kad mes norime „WidgetRepository“
Grįžti. Tada mes naudojame „Mockito“ API konfigūruoti „WidgetRepository“ :: findById
metodas. Mūsų bandomosios logikos struktūra yra tokia:
„doReturn“ (VALUE_TO_RETURN). kai (MOCK_CLASS_INSTANCE). MOCK_METHOD
Šiuo atveju sakome: grąžinti an Neprivaloma
mūsų Valdiklis
kai kapinyno „findById“ ()
metodas iškviečiamas argumentu 1 (kaip a ilgas
).
Toliau mes pasitelkiame „WidgetService“
's findById
metodas su argumentu 1. Tada mes patvirtiname, kad jis yra ir kad grąžinamas Valdiklis
yra tas, kurį mes sukonfigūravome „WidgetRepository“
Grįžti.