Testovanie v Spring Boot

1. Prehľad

V tejto príručke sa pozrieme na písanie testov pomocou podpory frameworku vo Spring Boot. Pokryjeme jednotkové testy, ktoré môžu bežať izolovane, ako aj integračné testy, ktoré pred vykonaním testov zavedú kontext Spring.

Ak ste v Spring Boot nováčikom, pozrite si naše úvodné predstavenie Spring Boot.

2. Nastavenie projektu

Aplikácia, ktorú použijeme v tomto článku, je API, ktoré poskytuje niektoré základné operácie so serverom Zamestnanec Zdroj. Toto je typická viacúrovňová architektúra - volanie API sa spracováva z Kontrolór do Služby do Vytrvalosť vrstva.

3. Závislosti Maven

Najprv pridajme naše testovacie závislosti:

 test org.springframework.boot test Spring-Boot-Starter-Test 2.2.6. RELEASE com.h2database h2 test 

The test štartovacej pružiny je primárna závislosť, ktorá obsahuje väčšinu prvkov požadovaných pre naše testy.

H2 DB je naša databáza v pamäti. Eliminuje potrebu konfigurácie a spustenia skutočnej databázy na testovacie účely.

4. Testovanie integrácie s @DataJpaTest

Budeme pracovať s entitou s menom Zamestnanec, ktorý má id a a názov ako jeho vlastnosti:

@Entity @Table (name = "person") verejná trieda Zamestnanec {@Id @GeneratedValue (strategy = GenerationType.AUTO) private Long id; @ Veľkosť (min = 3, max = 20) súkromné ​​meno reťazca; // štandardní zakladatelia a zakladatelia, konštruktory}

A tu je naše úložisko využívajúce Spring Data JPA:

@Repository verejné rozhranie EmployeeRepository rozširuje JpaRepository {public Employee findByName (názov reťazca); }

To je všetko pre kód vrstvy perzistencie. Poďme teraz k napísaniu našej testovacej triedy.

Najskôr vytvorme kostru našej testovacej triedy:

@RunWith (SpringRunner.class) @DataJpaTest verejná trieda EmployeeRepositoryIntegrationTest {@Autowired private TestEntityManager entityManager; @Autowired private EmployeeRepository employeeRepository; // sem napíš testovacie prípady}

@RunWith (SpringRunner.class) poskytuje prepojenie medzi funkciami testovania Spring Boot a JUnit. Kedykoľvek používame v testoch JUnit akékoľvek funkcie testovania Spring Boot, bude táto anotácia vyžadovaná.

@DataJpaTest poskytuje štandardné nastavenie potrebné na testovanie vrstvy perzistencie:

  • konfigurácia H2, databázy v pamäti
  • nastavenie režimu dlhodobého spánku, jarných údajov a Dátový zdroj
  • vykonávajúci @EntityScan
  • zapnutie logovania SQL

Na vykonávanie operácií DB potrebujeme nejaké záznamy, ktoré sú už v našej databáze. Na nastavenie týchto údajov môžeme použiť TestEntityManager.

Jarná topánka TestEntityManager je alternatívou k štandardnému JPA EntityManager ktorá poskytuje metódy bežne používané pri písaní testov.

Úložisko zamestnancov je komponent, ktorý ideme testovať.

Teraz napíšme náš prvý testovací prípad:

@Test public void whenFindByName_thenReturnEmployee () {// daný zamestnanec alex = nový zamestnanec ("alex"); entityManager.persist (alex); entityManager.flush (); // keď bol nájdený zamestnanec = employeeRepository.findByName (alex.getName ()); // potom assertThat (found.getName ()) .isEqualTo (alex.getName ()); }

Vo vyššie uvedenom teste používame TestEntityManager vložiť Zamestnanec v DB a jeho načítanie cez API nájsť podľa názvu.

The tvrdiťTo (...) časť pochádza z knižnice Assertj, ktorá je dodávaná s balíkom Spring Boot.

5. Vysmievanie sa @MockBean

Náš Služby kód vrstvy je závislý na našom Úložisko.

Avšak na otestovanie Služby vrstvy, nemusíme vedieť alebo sa zaujímať o to, ako je implementovaná vrstva perzistencie:

@Service verejná trieda EmployeeServiceImpl implementuje EmployeeService {@Autowired private EmployeeRepository employeeRepository; @ Verejné zverejnenie Zamestnanec getEmployeeByName (názov reťazca) {návrat employeeRepository.findByName (meno); }}

V ideálnom prípade by sme mali byť schopní písať a testovať svoje Služby kód vrstvy bez zapojenia v našej úplnej vrstve perzistencie.

Aby ste to dosiahli, môžeme použiť posmešnú podporu, ktorú poskytuje Spring Boot Test.

Najprv sa pozrime na kostru testovacej triedy:

@RunWith (SpringRunner.class) verejná trieda EmployeeServiceImplIntegrationTest {@TestConfiguration statická trieda EmployeeServiceImplTestContextConfiguration {@Bean public EmployeeService employeeService () {return new EmployeeServiceImpl (); }} @Autowired private EmployeeService employeeService; @MockBean private EmployeeRepository employeeRepository; // sem napíš testovacie prípady}

Ak chcete skontrolovať Služby triedy, musíme mať inštanciu Služby trieda vytvorená a dostupná ako @Bean aby sme mohli @Autowire v našej testovacej triede. Túto konfiguráciu môžeme dosiahnuť pomocou @ TestConfiguration anotácia.

Počas skenovania komponentov by sme mohli zistiť, že komponenty alebo konfigurácie vytvorené iba pre konkrétne testy sa omylom všade zachytia. Aby ste tomu zabránili, Spring Boot poskytuje @ TestConfiguration anotácia, ktorú môžeme pridať k triedam v src / test / java čo naznačuje, že by sa nemali zachytávať skenovaním.

Ďalšou zaujímavou vecou je použitie @MockBean. Vytvára Mock pre Úložisko zamestnancov, ktorým je možné obísť hovor na skutočnú Úložisko zamestnancov:

@Before public void setUp () {Employee alex = new Employee ("alex"); Mockito.when (employeeRepository.findByName (alex.getName ())) .thenReturn (alex); }

Pretože je nastavenie hotové, testovací prípad bude jednoduchší:

@ Test public void whenValidName_thenEmployeeShouldBeFound () {Názov reťazca = "alex"; Nájdený zamestnanec = employeeService.getEmployeeByName (meno); assertThat (found.getName ()) .isEqualTo (name); }

6. Testovanie jednotky s @WebMvcTest

Náš Kontrolór záleží na Služby vrstva; zahrňme pre jednoduchosť iba jednu metódu:

@RestController @RequestMapping ("/ api") verejná trieda EmployeeRestController {@Autowired private EmployeeService employeeService; @GetMapping ("/ zamestnanci") verejný zoznam getAllEmployees () {návrat employeeService.getAllEmployees (); }}

Pretože sa zameriavame iba na Kontrolór kód, je prirodzené sa vysmievať Služby kód vrstvy pre naše jednotkové testy:

@RunWith (SpringRunner.class) @WebMvcTest (EmployeeRestController.class) verejná trieda EmployeeRestControllerIntegrationTest {@Autowired private MockMvc mvc; @MockBean súkromná služba EmployeeService; // sem napíš testovacie prípady}

Ak chcete otestovať Kontrolóri, môžeme použiť @WebMvcTest. Automaticky nakonfiguruje jarnú infraštruktúru MVC pre naše testovanie jednotiek.

Väčšinou, @WebMvcTest bude obmedzené na bootstrap jedného radiča. Môžeme ho použiť aj spolu s @MockBean poskytnúť simulované implementácie pre všetky požadované závislosti.

@WebMvcTest tiež automatické konfigurácie MockMvc, ktorý ponúka výkonný spôsob ľahkého testovania radičov MVC bez spustenia úplného servera HTTP.

Po tomto, napíšme náš testovací prípad:

@Test public void givenEmployees_whenGetEmployees_thenReturnJsonArray () vyvolá výnimku {Employee alex = new Employee ("alex"); Zoznam všetkých zamestnancov = Arrays.asList (alex); dané (service.getAllEmployees ()). willReturn (allEmployees); mvc.perform (get ("/ api / zamestnanci") .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isOk ()) .andExpect (jsonPath ("$", hasSize (1))) .andExpect ( jsonPath ("$ [0] .name", je (alex.getName ()))); }

The dostať (...) volanie metódy môže byť nahradené inými metódami zodpovedajúcimi slovesám HTTP ako put (), príspevok (), atď. Upozorňujeme, že v žiadosti nastavujeme aj typ obsahu.

MockMvc je flexibilný a pomocou neho môžeme vytvoriť akúkoľvek požiadavku.

7. Testovanie integrácie s @SpringBootTest

Ako už názov napovedá, integračné testy sa zameriavajú na integráciu rôznych vrstiev aplikácie. To tiež znamená, že nejde o žiadne zosmiešňovanie.

V ideálnom prípade by sme mali nechať integračné testy oddelené od jednotkových testov a nemali by sme bežať spolu s jednotkovými testami. Môžeme to urobiť tak, že na spustenie integračných testov použijeme iný profil. Môže to byť napríklad z toho dôvodu, že integračné testy sú časovo náročné a na vykonanie môže byť potrebná skutočná databáza.

Avšak v tomto článku sa na to nebudeme sústreďovať a namiesto toho použijeme úložisko H2 na perzistenciu v pamäti.

Integračné testy musia spustiť kontajner na vykonávanie testovacích prípadov. Preto je na to potrebné ďalšie nastavenie - to všetko je v Spring Boot jednoduché:

@RunWith (SpringRunner.class) @SpringBootTest (SpringBootTest.WebEnvironment.MOCK, classes = Application.class) @AutoConfigureMockMvc @TestPropertySource (locations = "classpath: application-integrationtest.properties") verejná trieda EmployeeRestControllerIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrationIntegrate @Autowired private EmployeeRepository repository; // sem napíš testovacie prípady}

The @SpringBootTest anotácia je užitočná, keď potrebujeme zaviesť celý kontajner. Anotácia funguje vytvorením súboru ApplicationContext ktoré budú použité v našich testoch.

Môžeme použiť webEnvironment atribút @SpringBootTest nakonfigurovať naše runtime prostredie; používame WebEnvironment.MOCK tu, aby kontajner fungoval v simulovanom prostredí servletov.

Ďalej @TestPropertySource anotácia pomáha konfigurovať umiestnenie súborov vlastností špecifických pre naše testy. Všimnite si, že súbor vlastností načítaný s @TestPropertySource prepíše existujúce application.properties spis.

The test integrácie aplikácie.vlastnosti obsahuje podrobnosti o konfigurácii perzistenčného úložiska:

spring.datasource.url = jdbc: h2: mem: test spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect

Ak chceme spustiť naše integračné testy proti MySQL, môžeme vyššie uvedené hodnoty zmeniť v súbore vlastností.

Testovacie prípady integračných testov môžu vyzerať podobne ako Kontrolór testy jednotkovej vrstvy:

@Test public void givenEmployees_whenGetEmployees_thenStatus200 () vyvolá výnimku {createTestEmployee ("bob"); mvc.perform (get ("/ api / zamestnanci") .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isOk ()) .andExpect (content () .contentTypeCompatibleWith (MediaType.APPLICATION_JSON)) .andExpect (json) ("$ [0] .name", je ("bob"))); }

Rozdiel od Kontrolór testy jednotkových vrstiev spočívajú v tom, že sa tu nič nevysmieva a vykonajú sa end-to-end scenáre.

8. Automaticky konfigurované testy

Jednou z úžasných funkcií automaticky konfigurovaných anotácií Spring Boot je, že pomáha načítať časti kompletnej aplikácie a vrstvy kódu špecifické pre test.

Okrem vyššie uvedených anotácií uvádzam aj zoznam niekoľkých často používaných anotácií:

  • @WebFluxTest: Môžeme použiť @WebFluxTest anotácia na testovanie jarných radičov WebFlux. Často sa používa spolu s @MockBean poskytnúť falošné implementácie pre požadované závislosti.
  • @JdbcTest: ŽMôžeme použiť @JdbcTest anotácia na testovanie aplikácií JPA, ale je to pre testy, ktoré vyžadujú iba a Dátový zdroj. Anotácia konfiguruje vloženú databázu v pamäti a JdbcTemplate.
  • @JooqTest: Na testovanie testov súvisiacich s jOOQ môžeme použiť @JooqTest anotácia, ktorá konfiguruje DSLContext.
  • @DataMongoTest: Ak chcete otestovať aplikácie MongoDB, @DataMongoTest je užitočná anotácia. Predvolene konfiguruje zabudovaný MongoDB v pamäti, ak je ovládač k dispozícii prostredníctvom závislostí, konfiguruje a MongoTemplate, vyhľadá @Dokument triedy a konfiguruje úložiská Spring Data MongoDB.
  • @DataRedisTestuľahčuje testovanie aplikácií Redis. Vyhľadáva @RedisHash triedy a predvolene konfiguruje úložiská Spring Data Redis.
  • @DataLdapTest konfiguruje vloženú pamäť LDAP (ak je k dispozícii), konfiguruje a LdapTemplate, vyhľadáva @ Vstup triedy a konfiguruje Spring Data LDAP úložiská predvolene.
  • @RestClientTest: Spravidla používame @RestClientTest anotácia na testovanie klientov REST. Automaticky konfiguruje rôzne závislosti, napríklad podporu Jacksonov, GSON a Jsonb; konfiguruje a RestTemplateBuilder; a pridáva podporu pre MockRestServiceServer predvolene.

9. Záver

V tomto článku sme sa podrobne ponorili do podpory testovania v Spring Boot a ukázali sme, ako efektívne písať jednotkové testy.

Celý zdrojový kód tohto článku nájdete na GitHub. Zdrojový kód obsahuje oveľa viac príkladov a rôzne testovacie prípady.

A ak sa chcete naďalej učiť o testovaní, máme v JUnit 5 samostatné články týkajúce sa integračných testov a jednotkových testov.


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