Programmēšana

JUnit 5 apmācība, 2. daļa: Pavasara MVC testēšana ar JUnit 5

Pavasara MVC ir viens no populārākajiem Java ietvariem uzņēmuma Java lietojumprogrammu veidošanai, un tas ļoti labi izmanto testēšanu. Pēc konstrukcijas Spring MVC veicina problēmu nošķiršanu un mudina kodēt pret saskarnēm. Šīs īpašības kopā ar pavasara īstenoto atkarības injekciju padara pavasara lietojumus ļoti pārbaudāmus.

Šī apmācība ir mana ievada otrā daļa vienību testēšanai ar JUnit 5. Es jums parādīšu, kā integrēt JUnit 5 ar Spring, pēc tam jūs iepazīstināšu ar trim rīkiem, kurus varat izmantot Spring MVC kontrolieru, pakalpojumu un krātuvju pārbaudei.

lejupielādēt Iegūt kodu Lejupielādējiet avota kodu, piemēram, šajā apmācībā izmantotajām lietojumprogrammām. Izveidoja Steven Haines JavaWorld.

JUnit 5 integrēšana ar 5. pavasari

Šajā apmācībā mēs izmantojam Maven un Spring Boot, tāpēc pirmā lieta, kas mums jādara, ir pievienot JUnit 5 atkarību mūsu Maven POM failam:

  org.junit.jupiter junit-jupiter 5.6.0 tests 

Tāpat kā mēs to darījām 1. daļā, šajā piemērā izmantosim arī Mockito. Tātad mums būs jāpievieno JUnit 5 Mockito bibliotēka:

  org.mockito mockito-junit-jupiter 3.2.4 tests 

@ExtendWith un SpringExtension klase

5. JUnit definē paplašinājuma saskarne, caur kuru klases var integrēties ar JUnit testiem dažādos izpildes dzīves cikla posmos. Paplašinājumus varam iespējot, pievienojot @ExtendWith anotācija mūsu testa klasēm un norādot ielādējamo paplašinājumu klasi. Pēc tam paplašinājums var ieviest dažādas atzvanīšanas saskarnes, kuras tiks izmantotas visā testa dzīves ciklā: pirms visi testi, pirms katra testa, pēc katra testa, un pēc tam, kad visi testi ir izpildīti.

Pavasaris nosaka a SpringExtension klase, kas abonē JUnit 5 dzīves cikla paziņojumus, lai izveidotu un uzturētu "testa kontekstu". Atgādināsim, ka Spring lietojumprogrammas konteksts satur visas pavasara pupiņas lietojumprogrammā un ka tas veic atkarības ievadīšanu, lai savienotu programmu un tās atkarības. Pavasaris izmanto JUnit 5 paplašinājuma modeli, lai uzturētu testa lietojumprogrammu kontekstu, kas padara vienības rakstīšanas testus vienkāršos.

Pēc tam, kad esam pievienojuši JUnit 5 bibliotēku savam Maven POM failam, mēs varam izmantot SpringExtension.class paplašināt mūsu JUnit 5 ieskaites klases:

 @ExtendWith (SpringExtension.class) klases MyTests {// ...}

Šajā gadījumā piemērs ir Spring Boot lietojumprogramma. Par laimi @SpringBootTest anotācijā jau ir iekļauts @ExtendWith (SpringExtension.class) anotācija, tāpēc mums tikai jāiekļauj @SpringBootTest.

Pievienojot Mockito atkarību

Lai pareizi pārbaudītu katru komponentu atsevišķi un simulētu dažādus scenārijus, mēs vēlēsimies izveidot izdomātus katras klases atkarību īstenojumus. Šeit ir vieta, kur ienāk Mockito. Lai pievienotu atbalstu Mockito, POM failā iekļaujiet šādu atkarību:

  org.mockito mockito-junit-jupiter 3.2.4 tests 

Kad esat integrējis JUnit 5 un Mockito savā Spring lietojumprogrammā, varat izmantot Mockito, vienkārši definējot pavasara pupiņu (piemēram, pakalpojumu vai repozitoriju) savā testa klasē, izmantojot @MockBean anotācija. Šis ir mūsu piemērs:

 @SpringBootTest publiskās klases WidgetServiceTest {/ ** * Autowire pakalpojumā, kuru vēlamies pārbaudīt * / @Autowired private WidgetService service; / ** * Izveidojiet WidgetRepository izspēles ieviešanu * / @MockBean private WidgetRepository repository; ...} 

Šajā piemērā mēs veidojam izspēli WidgetRepository iekšā mūsu WidgetServiceTest klasē. Kad pavasaris to redzēs, tas automātiski ieslēgs to mūsu tīklā WidgetService lai mēs savās testa metodēs varētu izveidot dažādus scenārijus. Katra testa metode konfigurēs WidgetRepository, piemēram, atdodot pieprasīto Logrīks vai atgriežat Neobligāti. Tukšs () vaicājumam, kuram dati nav atrasti. Mēs pavadīsim šīs apmācības atlikušo daļu, aplūkojot dažādus šo izspēlēto pupiņu konfigurēšanas veidu piemērus.

Pavasara MVC piemēru piemērs

Lai rakstītu pavasarī balstītus vienību testus, mums ir nepieciešama lietojumprogramma, pret kuru tos rakstīt. Par laimi, mēs varam izmantot manas lietojumprogrammas piemēru Pavasara sērija apmācība "Pavasara ietvara 5. apgūšana, 1. daļa: Pavasara MVC". Es izmantoju piemēru no šīs apmācības kā bāzes lietojumprogrammu. Es to pārveidoju ar spēcīgāku REST API, lai mums būtu jāpārbauda vēl dažas lietas.

Lietojumprogrammas piemērs ir pavasara MVC tīmekļa lietojumprogramma ar REST kontrolieri, pakalpojumu slāni un krātuvi, kas izmanto Spring Data JPA, lai saglabātu "logrīkus" H2 atmiņas datu bāzē un no tās. 1. attēls ir pārskats.

Stīvens Heinss

Kas ir logrīks?

A Logrīks ir tikai "lieta" ar ID, vārdu, aprakstu un versijas numuru. Šajā gadījumā mūsu logrīks tiek anotēts ar JPA anotācijām, lai to definētu kā entītiju. The WidgetRestController ir pavasara MVC kontrolieris, kas pārveido RESTful API izsaukumus darbībās, kurās veikt Logrīki. The WidgetService ir standarta pavasara pakalpojums, kas nosaka uzņēmuma funkcionalitāti Logrīki. Visbeidzot WidgetRepository ir Spring Data JPA saskarne, kurai Spring izpildes laikā izveidos ieviešanu. Rakstot testus nākamajās sadaļās, mēs pārskatīsim katras klases kodu.

Vienība pārbauda pavasara pakalpojumu

Sāksim ar pārskatīšanu, kā pārbaudīt pavasariapkalpošana, jo tas ir visvieglāk pārbaudāms mūsu MVC lietojumprogrammā. Šīs sadaļas piemēri ļaus mums izpētīt JUnit 5 integrāciju ar Spring, neieviešot jaunus testēšanas komponentus vai bibliotēkas, lai gan mēs to darīsim vēlāk apmācībā.

Mēs sāksim pārskatīt WidgetService interfeiss un WidgetServiceImpl klase, kas ir parādīti attiecīgi 1. un 2. sarakstā.

Saraksts 1. Pavasara servisa saskarne (WidgetService.java)

 pakete com.geekcap.javaworld.spring5mvcexample.service; importēt com.geekcap.javaworld.spring5mvcexample.model.Widget; importēt java.util.List; importēt java.util.Papildu; publiskā saskarne WidgetService {Izvēles findById (Long id); Saraksts findAll (); Logrīka saglabāšana (logrīka logrīks); void deleteById (garais id); }

2. saraksts. Pavasara pakalpojuma ieviešanas klase (WidgetServiceImpl.java)

 pakete com.geekcap.javaworld.spring5mvcexample.service; importēt com.geekcap.javaworld.spring5mvcexample.model.Widget; importēt com.geekcap.javaworld.spring5mvcexample.repository.WidgetRepository; importēt com.google.common.collect.Lists; importēt org.springframework.stereotype.Service; importēt java.util.ArrayList; importēt java.util.List; importēt java.util.Papildu; @Service publiskā klase WidgetServiceImpl ievieš WidgetService {privāto WidgetRepository repozitoriju; public WidgetServiceImpl (WidgetRepository repository) {this.repository = repozitorijs; } @Orride public Izvēles findById (Long id) {return repository.findById (id); } @Orride public List findAll () {return Lists.newArrayList (repository.findAll ()); } @Orride public Widget save (Widget widget) {// Palieliniet versijas numuru widget.setVersion (widget.getVersion () + 1); // Saglabājiet logrīku krātuvē atgriešanās krātuve.save (logrīks); } @Orride public void deleteById (Long id) {repository.deleteById (id); }}

WidgetServiceImpl ir pavasara dievkalpojums, kas anotēts ar @Apkalpošana anotācija, kurai ir WidgetRepository caur tā konstruktoru. The findById (), findAll (), un deleteById () metodes ir visas pārejas metodes uz pamata WidgetRepository. Vienīgā biznesa loģika, kuru atradīsit, atrodas saglabāt () metode, kas palielina versijas numuru Logrīks kad tas tiek saglabāts.

Pārbaudes klase

Lai pārbaudītu šo klasi, mums jāizveido un jākonfigurē izspēles WidgetRepository, vadu to WidgetServiceImpl piemēram, un pēc tam vadu WidgetServiceImpl mūsu pārbaudes klasē. Par laimi, tas ir daudz vieglāk, nekā izklausās. 3. sarakstā ir redzams WidgetServiceTest klasē.

3. saraksts. Pavasara servisa testa klase (WidgetServiceTest.java)

 pakete com.geekcap.javaworld.spring5mvcexample.service; importēt com.geekcap.javaworld.spring5mvcexample.model.Widget; importēt com.geekcap.javaworld.spring5mvcexample.repository.WidgetRepository; importēt org.junit.jupiter.api.Assertions; importēt org.junit.jupiter.api.DisplayName; importēt org.junit.jupiter.api.Test; importēt org.junit.jupiter.api.extension.ExtendWith; importēt org.springframework.beans.factory.annotation.Autowired; importēt org.springframework.boot.test.context.SpringBootTest; importēt org.springframework.boot.test.mock.mockito.MockBean; importēt org.springframework.test.context.junit.jupiter.SpringExtension; importēt java.util.Arrays; importēt java.util.List; importēt java.util.Papildu; importēt statisko org.mockito.Mockito.doReturn; importēt statisko org.mockito.ArgumentMatchers.any; @SpringBootTest publiskās klases WidgetServiceTest {/ ** * Autowire pakalpojumā, kuru vēlamies pārbaudīt * / @Autowired private WidgetService service; / ** * Izveidojiet izdomātu WidgetRepository * / @MockBean privāto WidgetRepository repozitorija ieviešanu; @Test @DisplayName ("Test findById Success") void testFindById () {// Iestatiet mūsu izspēles repozitoriju Logrīka logrīks = jauns logrīks (1l, "Logrīka nosaukums", "Apraksts", 1); doReturn (pēc izvēles (logrīks)). kad (krātuve) .findById (1l); // Izpildiet servisa izsaukumu Neobligāti returnWidget = service.findById (1l); // Apstipriniet atbildi Assertions.assertTrue (returnWidget.isPresent (), "Logrīks netika atrasts"); Assertions.assertSame (returnWidget.get (), logrīks, "Atdotais logrīks nebija tas pats, kas izspēles"); } @Test @DisplayName ("Test findById Not Found") void testFindByIdNotFound () {// Iestatiet mūsu izspēles repozitoriju doReturn (Optional.empty ()). When (repository) .findById (1l); // Izpildiet servisa izsaukumu Neobligāti ReturnWidget = service.findById (1l); // Apstipriniet atbildi Assertions.assertFalse (returnWidget.isPresent (), "Logrīku nevajadzētu atrast"); } @Test @DisplayName ("Test findAll") void testFindAll () {// Iestatiet mūsu izspēles repozitoriju Logrīka logrīks1 = jauns logrīks (1l, "Logrīka nosaukums", "Apraksts", 1); Logrīka logrīks2 = jauns logrīks (2l, "Logrīka 2 nosaukums", "Apraksts 2", 4); doReturn (Arrays.asList (widget1, widget2)). when (repozitorijs) .findAll (); // Izpildiet pakalpojumu izsaukuma saraksta logrīkus = service.findAll (); // Apstipriniet atbildi Assertions.assertEquals (2, widgets.size (), "findAll jāatdod 2 logrīki"); } @Test @DisplayName ("Test save widget") void testSave () {// Iestatiet mūsu izspēles krātuvi Logrīka logrīks = jauns logrīks (1l, "Logrīka nosaukums", "Apraksts", 1); doReturn (widget) .when (repozitorijs) .save (any () ()); // Izpildiet pakalpojuma izsaukuma logrīku ReturnWidget = service.save (logrīks); // Apstipriniet atbildi Assertions.assertNotNull (returnWidget, "Saglabātajam logrīkam nevajadzētu būt nullei"); Assertions.assertEquals (2, returnWidget.getVersion (), "Versija jāpalielina"); }} 

The WidgetServiceTest klase ir anotēta ar @SpringBootTest anotācija, kas skenē CLASSPATH visām pavasara konfigurācijas klasēm un pupiņām un testa klasei izveido pavasara lietojuma kontekstu. Pieraksti to WidgetServiceTest netieši ietver arī @ExtendWith (SpringExtension.class) anotācija, izmantojot @SpringBootTest anotācija, kurā testa klase tiek integrēta ar JUnit 5.

Pārbaudes klasē tiek izmantotas arī Spring's @Autowired anotācija automātiskai ievadīšanai a WidgetService lai pārbaudītu, un tas izmanto Mockito's @MockBean anotācija, lai izveidotu izspēli WidgetRepository. Šajā brīdī mums ir izspēles WidgetRepository ko mēs varam konfigurēt, un reāls WidgetService ar izspēli WidgetRepository vadu tajā.

Pārbauda pavasara dievkalpojumu

Pirmā testa metode, testFindById (), izpilda WidgetService's findById () metode, kurai jāatgriež Neobligāti kas satur a Logrīks. Mēs sākam, izveidojot Logrīks ka mēs vēlamies WidgetRepository Atgriezties. Pēc tam mēs izmantojam Mockito API, lai konfigurētu WidgetRepository :: findById metodi. Mūsu izspēles loģikas struktūra ir šāda:

 doReturn (VALUE_TO_RETURN). kad (MOCK_CLASS_INSTANCE). MOCK_METHOD 

Šajā gadījumā mēs sakām: Atgrieziet an Neobligāti no mūsu Logrīks kad krātuve findById () metodi izsauc ar argumentu 1 (kā a ilgi).

Tālāk mēs izmantojam WidgetService's findById metode ar argumentu 1. Pēc tam mēs apstiprinām, ka tā ir un ka tā ir atgriezta Logrīks ir tā, kuru mēs konfigurējām izspēli WidgetRepository Atgriezties.

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