Tesztelés tavaszi csomagtartóban

1. Áttekintés

Ebben az oktatóanyagban megnézzük tesztek írása a Spring Boot keretrendszer-támogatásával. Kitérünk olyan egységtesztekre, amelyek külön-külön is futtathatók, valamint olyan integrációs tesztekre, amelyek a tesztek végrehajtása előtt elindítják a Spring kontextust.

Ha Ön még nem ismeri a Spring Boot alkalmazást, nézze meg a Spring Boot bevezetőjét.

2. Projekt beállítása

A cikkben használni kívánt alkalmazás egy API, amely néhány alapvető műveletet biztosít a Munkavállaló Forrás. Ez egy tipikus többszintű architektúra - az API hívást a Vezérlő nak nek Szolgáltatás hoz Kitartás réteg.

3. Maven-függőségek

Először tegyük hozzá tesztelési függőségeinket:

 org.springframework.boot spring-boot-starter-test test 2.2.6. KÖZLEMÉNY com.h2database h2 teszt 

A tavasz-csomagtartó-indító-teszt az elsődleges függőség, amely a tesztjeinkhez szükséges elemek többségét tartalmazza.

A H2 DB a memóriánkban található adatbázisunk. Így nincs szükség tényleges adatbázis konfigurálására és indítására teszt céljából.

4. Integrációs tesztelés @DataJpaTest

Egy elnevezett entitással fogunk dolgozni Munkavállaló, amelynek van egy id és a név mint tulajdonságai:

@Entity @Table (name = "person") public class Employee {@Id @GeneratedValue (strategy = GenerationType.AUTO) private Long id; @Size (min = 3, max = 20) privát karakterlánc neve; // szabványos mérőeszközök és beállítók, kivitelezők}

És itt van a Spring Data JPA-t használó tárházunk:

@Repository nyilvános felület EmployeeRepository kiterjeszti a JpaRepository {public Employee findByName (karakterlánc neve); }

Ennyi a perzisztens réteg kódja. Most induljunk el a tesztóránk megírása felé.

Először hozzuk létre tesztosztályunk csontvázat:

@RunWith (SpringRunner.class) @DataJpaTest nyilvános osztály EmployeeRepositoryIntegrationTest {@Autowired private TestEntityManager entityManager; @Autowired private EmployeeRepository workerRepository; // írjon ide teszteseteket}

@RunWith (SpringRunner.class) hidat nyújt a Spring Boot tesztfunkciói és a JUnit között. Amikor a Spring Boot tesztelési funkciókat használjuk a JUnit tesztjeinkben, erre a megjegyzésre szükség lesz.

@DataJpaTest néhány alapvető beállítást biztosít a perzisztencia réteg teszteléséhez:

  • a H2, egy memóriában lévő adatbázis konfigurálása
  • a Hibernate, Spring Data és a Adatforrás
  • egy @EntityScan
  • az SQL naplózás bekapcsolása

A DB műveletek végrehajtásához néhány rekordra van szükségünk már az adatbázisunkban. Ezen adatok beállításához felhasználhatjuk TestEntityManager.

A tavaszi csizma TestEntityManager a JPA alternatívája EntityManager amely a tesztek írásakor általánosan használt módszereket biztosítja.

EmployeeRepository az a komponens, amelyet tesztelni fogunk.

Most írjuk meg az első tesztesetet:

@Test public void whenFindByName_thenReturnEmployee () {// adott alkalmazott alex = new Employee ("alex"); entitásMenedzser.perszisztens (alex); entitásManager.flush (); // amikor az Alkalmazott megtalálta = workerRepository.findByName (alex.getName ()); // majd assertThat (talált.getName ()) .isEqualTo (alex.getName ()); }

A fenti tesztben a TestEntityManager beilleszteni egy Munkavállaló a DB-ben, és elolvassa a név szerint történő keresés API-n keresztül.

A assertThat (…) rész az Assertj könyvtárból származik, amely a Spring Boot csomagban van.

5. Gúnyolódni @MockBean

A mi Szolgáltatás réteg kód függ a mi Adattár.

Azonban, hogy tesztelje a Szolgáltatás réteg, nem kell tudnunk, és nem kell törődnünk a perzisztencia réteg megvalósításával:

@Service public class EmployeeServiceImpl megvalósítja az EmployeeService {@Autowired private EmployeeRepository workerRepository; @Orride public Employee getEmployeeByName (String name) {return workerRepository.findByName (name); }}

Ideális esetben képesnek kell lennünk arra, hogy megírjuk és teszteljük Szolgáltatás rétegkód bekötés nélkül a teljes perzisztencia rétegünkben.

Elérni ezt, használhatjuk a Spring Boot Test által nyújtott gúnyos támogatást.

Először vessünk egy pillantást a tesztosztály vázára:

@RunWith (SpringRunner.class) public class EmployeeServiceImplIntegrationTest {@TestConfiguration statikus osztály EmployeeServiceImplTestContextConfiguration {@Bean public EmployeeService workerService () {return new EmployeeServiceImpl (); }} @Autowired private EmployeeService workerService; @MockBean private EmployeeRepository workerRepository; // írjon ide teszteseteket}

A Szolgáltatás osztály, rendelkeznünk kell a Szolgáltatás osztály létrehozva és elérhetőként elérhető @Bab hogy tudjunk @Autowire teszt osztályunkban. Ezt a konfigurációt a @TestConfiguration annotáció.

Az alkatrész-szkennelés során azt tapasztalhatjuk, hogy a csak bizonyos tesztekhez létrehozott komponenseket vagy konfigurációkat véletlenül mindenhol felveszik. Ennek megelőzése érdekében, A Spring Boot biztosítja a @TestConfiguration annotáció, amelyet felvehetünk az osztályokra src / test / java jelezni, hogy nem szabad szkenneléssel felvenni őket.

Egy másik érdekes dolog itt a @MockBean. Megalkotja a EmployeeRosory, amellyel megkerülhető a hívás a ténylegesig EmployeeRosory:

@ Nyilvános void előtt setUp () {Employee alex = new Employee ("alex"); Mockito.when (workerRepository.findByName (alex.getName ())) .thenReturn (alex); }

Mivel a beállítás elkészült, a teszteset egyszerűbb lesz:

@Test public void whenValidName_thenEmployeeShouldBeFound () {String name = "alex"; Alkalmazott megtalálva = workerService.getEmployeeByName (név); assertThat (talált.getName ()) .isEqualTo (név); }

6. Egység tesztelése @WebMvcTest

A mi Vezérlő attól függ Szolgáltatás réteg; az egyszerűség kedvéért csak egyetlen módszert adjunk meg:

@RestController @RequestMapping ("/ api") nyilvános osztály EmployeeRestController {@Autowired private EmployeeService workerService; @GetMapping ("/ alkalmazottak") public list getAllEmployees () {return workerService.getAllEmployees (); }}

Mivel csak a Vezérlő kódot, természetes, hogy gúnyolják a Szolgáltatás rétegkód egységtesztjeinkhez:

@RunWith (SpringRunner.class) @WebMvcTest (EmployeeRestController.class) nyilvános osztály EmployeeRestControllerIntegrationTest {@Autowired private MockMvc mvc; @MockBean privát EmployeeService szolgáltatás; // írjon ide teszteseteket}

Kipróbálni a Vezérlők, tudjuk használni @WebMvcTest. Automatikusan konfigurálja a Spring MVC infrastruktúrát egységeink tesztjeihez.

A legtöbb esetben, @WebMvcTest csak egy vezérlő rendszerbetöltésére korlátozódik. Használhatjuk vele együtt is @MockBean hogy az esetleges függőségek számára kivitelezett megvalósításokat nyújtson.

@WebMvcTest automatikusan konfigurál MockMvc, amely hatékony módot kínál az MVC vezérlők egyszerű tesztelésére a teljes HTTP szerver indítása nélkül.

Ezt követően írjuk meg a tesztesetünket:

@Test public void givenEmployees_whenGetEmployees_thenReturnJsonArray () dobja a Kivételt {Employee alex = new Employee ("alex"); List allEmployees = Arrays.asList (alex); adott (service.getAllEmployees ()). willReturn (allEmployees); mvc.perform (get ("/ api / alkalmazottak") .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isOk ()) .andExpect (jsonPath ("$", hasSize (1))) .andExpect ( jsonPath ("$ [0] .name", az (alex.getName ()))); }

A kap(…) A metódus-hívás helyettesíthető más, a HTTP igéknek megfelelő módszerekkel, például put (), post ()stb. Felhívjuk figyelmét, hogy a kérelemben beállítjuk a tartalom típusát is.

MockMvc rugalmas, és bármilyen kérést létrehozhatunk felhasználásával.

7. Integrációs tesztelés @SpringBootTest

Ahogy a neve is sugallja, az integrációs tesztek az alkalmazás különböző rétegeinek integrálására összpontosítanak. Ez azt is jelenti, hogy nincs gúny.

Ideális esetben az integrációs teszteket el kell különítenünk az egységtesztektől, és ne fussunk együtt az egységtesztekkel. Ezt úgy tehetjük meg, hogy egy másik profilt használunk az integrációs tesztek futtatásához. Ennek néhány oka lehet, hogy az integrációs tesztek időigényesek, és a végrehajtáshoz tényleges adatbázisra lehet szükség.

Ebben a cikkben azonban nem erre összpontosítunk, és inkább a memóriában lévő H2 perzisztencia tárolót fogjuk használni.

Az integrációs teszteknek tárolót kell indítaniuk a tesztesetek végrehajtásához. Ezért ehhez további beállításokra van szükség - mindez a Spring Boot-ban egyszerű:

@RunWith (SpringRunner.class) @SpringBootTest (SpringBootTest.WebEnvironment.MOCK, class = Application.class) @AutoConfigureMockMvc @TestPropertySource (locations = "classpath: application-integrationtest.properties") public class EmployeeRestCv @Autowired private EmployeeRepository repository; // írjon ide teszteseteket}

A @SpringBootTest az annotáció akkor hasznos, ha a teljes konténert indítanunk kell. Az annotáció a ApplicationContext hogy felhasználják a tesztjeink során.

Használhatjuk a webEnvironment attribútuma @SpringBootTest futásidejű környezetünk konfigurálása; használjuk WebEnvironment.MOCK itt, hogy a konténer egy szervlet kisérleti környezetben működjön.

Ezután a @TestPropertySource az annotáció segít konfigurálni a tesztjeinkre jellemző tulajdonságfájlok helyét. Ne feledje, hogy a tulajdonságfájl a következővel lett betöltve: @TestPropertySource felülírja a meglévőt alkalmazás.tulajdonságok fájl.

A application-integrationtest.properties tartalmazza a perzisztencia tároló konfigurálásának részleteit:

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

Ha a MySQL-hez akarjuk futtatni az integrációs tesztjeinket, megváltoztathatjuk a fenti értékeket a tulajdonságfájlban.

Az integrációs tesztek tesztesetei hasonlóak lehetnek a Vezérlő réteg egység tesztek:

@Test public void givenEmployees_whenGetEmployees_thenStatus200 () dobja a Kivételt {createTestEmployee ("bob"); mvc.perform (get ("/ api / alkalmazottai") .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isOk ()) .andExpect (content () .contentTypeCompatibleWith (MediaType.APPLICATION_Jxpath) (and). ("$ [0] .name", is ("bob"))); }

A különbség a Vezérlő réteg egység tesztek szerint itt semmit sem csúfolnak és végpontok közötti forgatókönyvek kerülnek végrehajtásra.

8. Automatikusan konfigurált tesztek

A Spring Boot automatikusan konfigurált kommentárjainak egyik csodálatos tulajdonsága, hogy segít a teljes alkalmazás egyes részeinek és a kódalap teszt-specifikus rétegeinek betöltésében.

A fent említett feliratokon kívül, itt találunk néhány széles körben használt feljegyzés felsorolását:

  • @WebFluxTest: Használhatjuk a @WebFluxTest annotáció a Spring WebFlux vezérlők teszteléséhez. Gyakran használják együtt @MockBean hogy a szükséges függőségek számára kivitelezett megvalósításokat biztosítson.
  • @JdbcTest: We használhatja a @JdbcTest jelölés a JPA alkalmazások teszteléséhez, de csak azokra a tesztekre vonatkozik, amelyek csak a Adatforrás. Az annotáció a memóriában beágyazott adatbázist és a JdbcTemplate.
  • @JooqTest: A jOOQ-val kapcsolatos tesztek teszteléséhez használhatjuk @JooqTest annotáció, amely konfigurál egy DSLContext-et.
  • @DataMongoTest: A MongoDB alkalmazások teszteléséhez @DataMongoTest hasznos feljegyzés. Alapértelmezés szerint a memóriában beágyazott MongoDB-t konfigurál, ha az illesztőprogram függőségeken keresztül elérhető, MongoTemplate, után kutat @Dokumentum osztályokat, és konfigurálja a Spring Data MongoDB adattárakat.
  • @DataRedisTestmegkönnyíti a Redis alkalmazások tesztelését. Megvizsgálja @RedisHash osztályozza és alapértelmezés szerint konfigurálja a Spring Data Redis adattárakat.
  • @DataLdapTest konfigurál egy beágyazott memóriát LDAP (ha elérhető), konfigurálja a LdapTemplate, keres @Belépés osztályokat, és konfigurálja a Spring Data-t LDAP tárolók alapértelmezés szerint.
  • @RestClientTest: Általában a @RestClientTest jelölés a REST kliensek teszteléséhez. Automatikusan konfigurálja a különböző függőségeket, például a Jackson, a GSON és a Jsonb támogatást; konfigurálja a RestTemplateBuilder; és támogatást ad hozzá MockRestServiceServer alapértelmezés szerint.

9. Következtetés

Ebben a cikkben mélyen elmélyültünk a Spring Boot tesztelési támogatásában, és megmutattuk, hogyan lehet hatékonyan írni az egység teszteket.

A cikk teljes forráskódja megtalálható a GitHub oldalon. A forráskód még sok példát és különféle teszteseteket tartalmaz.

És ha tovább akarja tanulni a tesztelést, külön cikkeket találunk az integrációs tesztekkel és az egység tesztekkel kapcsolatban az 5. JUnit-ben.