Integrációs tesztelés tavasszal

1. Áttekintés

Az integráció tesztelése fontos szerepet játszik az alkalmazás fejlesztési ciklusában, mivel ellenőrzi a rendszer végpontok közötti viselkedését.

Ebben a cikkben megtudjuk, hogyan használhatjuk fel a Spring MVC teszt keretrendszerét olyan integrációs tesztek írásához és futtatásához, amelyek tesztelik a vezérlőket anélkül, hogy kifejezetten elindítanánk a Servlet-tárolót.

2. Előkészítés

A cikkben leírt integrációs tesztek futtatásához a következő Maven-függőségekre van szükség. Elsősorban a legújabb JUnit és Spring tesztfüggőségek:

 junit junit 4.12 teszt org.springframework tavaszi teszt 4.3.2.KÖZLÍTÉSI teszt 

Az eredmények hatékony érvényesítéséhez a Hamcrest és a JSON elérési utat is használni fogjuk:

 org.hamcrest hamcrest-library 1.3 teszt com.jayway.jsonpath json-path 2.2.0 teszt 

3. Tavaszi MVC teszt konfiguráció

Bemutatjuk, hogyan kell konfigurálni és futtatni a Spring engedélyezett teszteket.

3.1. Engedélyezze a tavaszt a tesztekben

Először minden tavasszal engedélyezett teszt a @RunWith (SpringJUnit4ClassRunner.class); a futó lényegében a belépési pont a Spring Test keretrendszer használatának megkezdéséhez.

Szükségünk van a @ContextConfiguration megjegyzéseket a kontextus konfigurációjának betöltéséhez és bootstrap a teszt által használt kontextust.

Nézzük meg:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (class = {ApplicationConfig.class}) @WebAppConfiguration nyilvános osztály GreetControllerIntegrationTest {....}

Figyelje meg, hogyan @ContextConfiguration, mi biztosítottuk a ApplicationConfig.class config osztály, amely betölti az adott teszthez szükséges konfigurációt.

Itt egy Java konfigurációs osztályt használtunk a kontextus konfigurációjának megadásához; hasonlóan használhatjuk az XML-alapú konfigurációt:

@ContextConfiguration (helyek = {""})

Végül - a tesztet szintén meg kell jegyezni @WebAppConfiguration - amely betölti a webalkalmazás kontextust.

Alapértelmezés szerint a gyökér webalkalmazást keresi az alapértelmezett elérési útvonalon src / main / webapp; a hely felülírható a érték attribútum:

@WebAppConfiguration (érték = "")

3.2. A WebApplicationContext Tárgy

WebApplicationContext (wac) webalkalmazás-konfigurációt biztosít. Betölti az összes alkalmazásbabot és vezérlőt a kontextusba.

Mostantól képes leszünk a webalkalmazás kontextusát közvetlenül a tesztbe vezetni:

@Autowired private WebApplicationContext wac;

3.3. A webes kontextus babjának gúnyolódása

MockMvc támogatást nyújt a tavaszi MVC teszteléshez. Az összes webalkalmazás babot összefoglalja, és tesztelésre elérhetővé teszi.

Nézzük meg, hogyan kell használni:

privát MockMvc mockMvc; @A nyilvános érvénytelen beállítás () előtt a (z) kivétel kiveti a {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .build (); }

Inicializálnunk kell a gúnyMvc objektum a @Előtt kommentált módszer, így nem kell inicializálnunk minden teszten belül.

3.4. Ellenőrizze a tesztkonfigurációt

Az itt bemutatott oktatóanyagunkhoz igazoltan ellenőrizzük, hogy betöltjük-e a WebApplicationContext tárgy (wac) megfelelően. Azt is ellenőrizni fogjuk, hogy a jog servletContext csatolva van:

@Test public void givenWac_whenServletContext_thenItProvidesGreetController () {ServletContext servletContext = wac.getServletContext (); Assert.assertNotNull (servletContext); Assert.assertTrue (a MockServletContext szervletContext példánya); Assert.assertNotNull (wac.getBean ("greetController")); }

Figyelje meg, hogy azt is ellenőrizzük, hogy a GreetController.java bab létezik a webes kontextusban - ami biztosítja a tavaszi bab megfelelő betöltését.

Ekkor elkészült az integrációs teszt beállítása. Nézzük meg, hogyan tesztelhetjük az erőforrás-módszereket a MockMvc tárgy.

4. Integrációs tesztek írása

Ebben a szakaszban áttekintjük a tesztkereten keresztül elérhető alapvető műveleteket.

Megmutatjuk, hogyan küldhetünk el kéréseket útváltozókkal és paraméterekkel. Ezenkívül néhány példát követünk, amelyek bemutatják, hogyan lehet azt állítani, hogy a nézet megfelelő neve fel van oldva, vagy hogy a válasz test a vártnak felel meg.

A következő kivonatok statikus importálást használnak az M-bőlockMvcRequestBuilders vagy MockMvcResultMatchers osztályok.

4.1. Ellenőrizze a nézet nevét

Hívjuk meg a / homePage végpont a tesztünkből as:

// localhost: 8080 / spring-mvc-test /

vagy

// localhost: 8080 / spring-mvc-test / homePage

Kódrészlet:

@Test public void givenHomePageURI_whenMockMVC_thenReturnsIndexJSPViewName () {this.mockMvc.perform (get ("/ homePage")). AndDo (print ()) .andExpect (view (). Name ("index")); }

Bontjuk le ezt:

  • teljesít () metódus hív egy lekérési metódust, amely visszaadja a ResultActions. Ennek az eredménynek a felhasználásával állítási elvárásaink lehetnek olyan válaszokkal kapcsolatban, mint a tartalom, a HTTP állapot, a fejléc stb
  • andDo (print ()) kinyomtatja a kérést és a választ. Ez hasznos ahhoz, hogy hiba esetén részletes képet kapjon
  • andExpect ()elvárja a megadott érvet. Esetünkben arra számítunk, hogy az „index” visszaküldésre kerül MockMvcResultMatchers.view ()

4.2. Ellenőrizze a válasz testet

Fel fogjuk hívni /üdvözöl tesztünk végpontja:

// localhost: 8080 / spring-mvc-test / greet

Várható teljesítmény:

{"id": 1, "message": "Hello World !!!" }

Kódrészlet:

@Test public void givenGreetURI_whenMockMVC_thenVerifyResponse () {MvcResult mvcResult = this.mockMvc.perform (get ("/ greet")) .andDo (print ()). ÉsExpect (status (). IsOk ()) .Expect (jsonP) .üzenet "). value (" Hello World !!! ")) .andReturn (); Assert.assertEquals ("application / json; charset = UTF-8", mvcResult.getResponse (). GetContentType ()); }

Nézzük meg pontosan, mi történik:

  • andExpect (MockMvcResultMatchers.status (). isOk ())ellenőrzi, hogy a válasz HTTP állapota-e Rendben azaz 200. Ez biztosítja a kérés sikeres végrehajtását
  • andExpect (MockMvcResultMatchers.jsonPath (“$. message”). érték (“Hello World !!!”)) ellenőrzi, hogy a válasz tartalma megegyezik-e az argumentummalHelló Világ!!!“. Itt használtuk jsonPath amely kivonja a válasz tartalmát és megadja a kért értéket
  • andReturn ()visszaadja a MvcResult objektum, amelyet akkor használunk, ha valamit ellenőriznünk kell, amelyet a könyvtár nem ér el. Láthatja, hogy hozzáadtuk assertEquals hogy megfeleljen a válasz tartalomtípusának MvcResult tárgy

4.3. Küldés KAP Kérés útváltozóval

Fel fogjuk hívni / greetWithPathVariable / {név} tesztünk végpontja:

// localhost: 8080 / spring-mvc-test / greetWithPathVariable / John

Várható teljesítmény:

{"id": 1, "message": "Szia John John !!!" }

Kódrészlet:

@Test public void givenGreetURIWithPathVariable_whenMockMVC_thenResponseOK () {this.mockMvc .perform (get ("/ greetWithPathVariable / {name}", "John")) .andDo (print ()). AndExpect (status () .Ok ()). (content (). contentType ("application / json; charset = UTF-8")) .andExpect (jsonPath ("$. message"). value ("Hello World John !!!")); }

MockMvcRequestBuilders.get (“/ greetWithPathVariable / {name}”, “John”) elküldi a kérést/ greetWithPathVariable / John“.

Ez könnyebbé válik az olvashatóság szempontjából, és annak ismeretében, hogy milyen paraméterek vannak dinamikusan beállítva az URL-ben. Vegye figyelembe, hogy annyi útparamétert adhatunk át, amennyi szükséges.

4.4. Küld KAP Kérés lekérdezési paraméterekkel

Fel fogjuk hívni / greetWithQueryVariable? name = {name} tesztünk végpontja:

// localhost: 8080 / spring-mvc-test / greetWithQueryVariable? name = John% 20Doe

Várható teljesítmény:

{"id": 1, "message": "Helló világ, John Doe !!!" }

Kódrészlet:

@Test public void givenGreetURIWithQueryParameter_whenMockMVC_thenResponseOK () {this.mockMvc.perform (get ("/ greetWithQueryVariable") .param ("name", "John Doe").) AndDo (print ()). ÉsExpO (status (). )) .andExpect (content (). contentType ("application / json; charset = UTF-8")) .andExpect (jsonPath ("$. message"). value ("Hello World John Doe !!!")); }

param („név”, „John Doe”) hozzáfűzi a lekérdezési paramétert a KAP kérés. Hasonló a / greetWithQueryVariable? name = John% 20Doe“.

A lekérdezési paraméter az URI sablon stílusával is megvalósítható:

this.mockMvc.perform (get ("/ greetWithQueryVariable? name = {name}", "John Doe"));

4.5. Küld POST Kérés

Fel fogjuk hívni / greetWithPost tesztünk végpontja:

// localhost: 8080 / spring-mvc-test / greetWithPost

Várható teljesítmény:

{"id": 1, "message": "Hello World !!!" }

Kódrészlet:

@Test public void givenGreetURIWithPost_whenMockMVC_thenVerifyResponse () {this.mockMvc.perform (post ("/ greetWithPost")). AndDo (print ()) .ésExpect (status (). IsOk ()). ÉsExpect (content () .contentType application / json; charset = UTF-8 ")) .andExpect (jsonPath (" $. message "). value (" Hello World !!! ")); }

MockMvcRequestBuilders.post (“/ greetWithPost”) elküldi a postakérelmet. Az útváltozók és a lekérdezési paraméterek hasonló módon állíthatók be, mint korábban, míg az űrlapadatok a param () csak a Query Parameterhez hasonló módszer, mint:

// localhost: 8080 / spring-mvc-test / greetWithPostAndFormData

Űrlapadatok:

id = 1; név = János% 20Doe

Várható teljesítmény:

{"id": 1, "message": "Helló világ, John Doe !!!" }

Kódrészlet:

@Test public void givenGreetURIWithPostAndFormData_whenMockMVC_thenResponseOK () {this.mockMvc.perform (post ("/ greetWithPostAndFormData"). Param ("id", "1") .param ("név", "John Doe")) és Do (nyomtassa (nyomtassa ( )). ésExpect (status (). isOk ()) .andExpect (content (). contentType ("alkalmazás / json; charset = UTF-8")) .andExpect (jsonPath ("$. üzenet"). érték (" Hello World John Doe !!! ")) .andExpect (jsonPath (" $. Id "). Érték (1)); }

A fenti kódrészletben két paraméter-azonosítót „1” névvel, a nevet pedig „John Doe” névvel egészítettünk ki.

5. MockMvc Korlátozások

MockMvc elegáns és könnyen használható API-t kínál a web-végpontok hívására, valamint a válaszok ellenőrzésére és érvényesítésére egyszerre. Minden előnye ellenére van néhány korlátozása.

Először is a DispatcherServlet tesztkérések kezelésére. Pontosabban: a TestDispatcherServlet felelős a vezérlők hívásáért és az összes ismert tavaszi varázslat végrehajtásáért.

A MockMvc osztály ezt burkolja TestDispatcherServlet belsőleg. Tehát minden alkalommal, amikor a teljesít () módszer, MockMvc az alapul szolgáló eszközt fogja használni TestDispatcherServlet közvetlenül. Ebből kifolyólag, nincsenek valós hálózati kapcsolatok, következésképpen nem teszteljük a teljes hálózati verem használatát MockMvc.

Is,Mivel a Spring hamis webalkalmazás-kontextust készít a HTTP-kérések és válaszok kigúnyolására, előfordulhat, hogy nem támogatja a teljes körű Spring-alkalmazás összes funkcióját.

Például ez az ál-beállítás nem támogatja a HTTP-átirányításokat. Ez elsőre talán nem tűnik annyira jelentősnek. A Spring Boot azonban néhány hibát úgy kezel, hogy átirányítja az aktuális kérést a /hiba végpont. Tehát ha a MockMvc, előfordulhat, hogy nem tudjuk tesztelni az API egyes hibáit.

A MockMvc, létrehozhatunk egy valósabb alkalmazási kontextustmajd használd RestTemplate vagy akár megnyugodhat, hogy tesztelje alkalmazásunkat.

Például ez egyszerű a Spring Boot használatával:

@RunWith (SpringRunner.class) @SpringBootTest (webEnvironment = RANDOM_PORT) nyilvános osztály GreetControllerRealIntegrationTest {@LocalServerPort privát int port; @ Nyilvános void előtt setUp () {RestAssured.port = port; } @Test public void givenGreetURI_whenSendingReq_thenVerifyResponse () {given (). Get ("/ greet") .then () .statusCode (200); }}

Így minden teszt valódi HTTP-kérést fog küldeni az alkalmazás számára, amely véletlenszerű TCP-portot hallgat.

6. Következtetés

Ebben az oktatóanyagban végrehajtottunk néhány egyszerű tavaszi integrációs tesztet.

Megnéztük a WebApplicationContext és MockMVC az objektum létrehozása, amely fontos szerepet játszott az alkalmazás végpontjainak meghívásában.

Tovább nézve kitértünk arra, hogyan tudunk küldeni KAP és POST kérések a paraméterek átadásának variációival, valamint a HTTP válasz állapotának, fejlécének és tartalmának ellenőrzésével.

Záró megjegyzésként értékeltük a MockMvc. E korlátok ismerete arra ösztönözhet minket, hogy megalapozott döntést hozzunk arról, hogy miként fogjuk végrehajtani tesztjeinket.

Végül mindezen példák és kódrészletek megvalósítása elérhető a GitHub-ban.