MockMvc

All lectures for UZ purposes
Daraja, Dars
Mavjud

Test tayyorlash uchun Spring MVC Test framework, shuningdek, MockMvc deb ham tanilgan, Spring MVC ilovalarini sinashni qo'llab-quvvatlaydi. U Spring MVC so'rovlarini to'liq ishlov berishni amalga oshiradi, lekin bu ishlovchi server o'rniga simulyatsiya qilingan so'rov-objekt va javob-objektlaridan foydalanadi.

MockMvc'ni alohida so'rovlar bajarish va javoblarni tekshirish uchun ishlatishingiz mumkin. Shuningdek, uni WebTestClient orqali ishlatishingiz mumkin, bu yerda MockMvc server sifatida so'rovlarni ishlov beradigan qilib tayinlanadi. WebTestClient ning afzalligi shundaki, u xom ma'lumotlar o'rniga yuqori darajadagi obyektlar bilan ishlash imkonini beradi va real serverda to'liq HTTP testlarni o'tkazish imkoniyatini beradi, bu barcha test API interfeysini ishlatish bilan birga.

Qisqa ta'rif

Spring MVC uchun oddiy modul testlarini yozish mumkin, bu orqali controller nusxalarini yaratish, unga bog'liqliklarni ulash va uning metodlarini chaqirish mumkin bo'ladi. Biroq, bunday testlar so'rovlarni moslashtirish, ma'lumotlarni bog'lash, xabarlarni o'zgartirish, turlarni o'zgartirish, validatsiya qilishni tekshirmaydi, shuningdek, @InitBinder, @ModelAttribute yoki @ExceptionHandler bilan anotatsiyalangan yordamchi metodlarni jalb qilmaydi.

Spring MVC Test framework, shuningdek MockMvc deb ham tanilgan, Spring MVC controllerlarini ishchi serverdan foydalanmasdan to'liqroq sinash uchun mo'ljallangan. Bu DispatcherServlet'ni chaqirib va servlet API interfeyslarining simulyatsiya qilingan realizatsiyalari'ni spring-test modulidan olib o'tish orqali, bu orqali ishlovchi serverisiz Spring MVC so'rovlarini to'liq ishlov berishni taqlid qiladi.

MockMvc - bu server tomonidagi test framework bo'lib, u Spring MVC ilovasining ko'p qirralik funksionalliklarini yengil va maqsadli testlar orqali tekshirish imkonini beradi. Uni alohida so'rovlar bajarish va javoblarni tekshirish uchun ishlatishingiz mumkin yoki uni WebTestClient API interfeysi orqali ulash mumkin, bu yerda MockMvc server sifatida so'rovlarni ishlov berish uchun tayinlangan.

Statik import qilish

Agar MockMvc'ni to'g'ridan-to'g'ri so'rovlar bajarish uchun ishlatsangiz, statik import qilish kerak bo'ladi:

  • MockMvcBuilders.*

  • MockMvcRequestBuilders.*

  • MockMvcResultMatchers.*

  • MockMvcResultHandlers.*

Ularni eslab qolishning oddiy usuli bu MockMvc* orqali qidirish. Agar siz Eclipse'dan foydalansangiz, ushbu statik a'zolarni "yaxshi ko'rilgan" ro'yxatiga qo'shishni unutmang.

Agar MockMvc'ni WebTestClient orqali ishlatsangiz, statik import qilishga hojat qolmaydi. WebTestClient statik import qilishsiz silliq API interfeysini taqdim etadi.

O'rnatish parametrlar

MockMvc ikki usuldan biri bilan sozlanishi mumkin. Birinchisi, sinov qilish kerak bo'lgan controllerlarga to'g'ridan-to'g'ri ko'rsatish, va Spring MVC infratuzilmasini dasturiy ravishda sozlash. Ikkinchisi, Spring MVC'ni va u ichidagi controller infratuzilmasini ishlatishda Spring konfiguratsiyasiga ko'rsatish.

Muayyan controllerni sinash uchun MockMvc'ni sozlash uchun quyidagilarni ishlating:

Java
class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
    }
    // ...
}
Kotlin
class MyWebTests {
    lateinit var mockMvc : MockMvc
    @BeforeEach
    fun setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(AccountController()).build()
    }
    // ...
}

Yoki siz bu sozlashni WebTestClient orqali test qilishda ham ishlatishingiz mumkin, yuqorida ko'rsatilgandek xizmatni qurish vazifasini berilgan.

MockMvc'ni Spring konfiguratsiyasi orqali sozlash uchun quyidagilarni ishlating:

Java
@SpringJUnitWebConfig(locations = "my-servlet-context.xml")
class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup(WebApplicationContext wac) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }
    // ...
}
Kotlin
@SpringJUnitWebConfig(locations = ["my-servlet-context.xml"])
class MyWebTests {
    lateinit var mockMvc: MockMvc
    @BeforeEach
    fun setup(wac: WebApplicationContext) {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
    }
    // ...
}

Yoki siz bu sozlashni WebTestClient orqali test qilishda ham ishlatishingiz mumkin, yuqorida ko'rsatilgandek xizmatni qurish vazifasini berilgan.

Qaysi sozlash variantini ishlatish kerak?

webAppContextSetup haqiqiy Spring MVC konfiguratsiyasini yuklaydi, bu to'liqroq integratsiya testi o'tkazishni ta'minlaydi. TestContext framework yuklangan Spring konfiguratsiyasini keshlagani tufayli, bu testlarni qabul qilishni tezlashtirishga yordam beradi, hatto siz test to'plamingizga ko'proq testlar kiritayotgan bo'lsangiz ham. Bundan tashqari, Spring konfiguratsiyasi yordamida controllerlarda simulatsiya qilingan xizmatlarni kiritishingiz mumkin, voyeb darajasida test qilishga e'tibor qaratsangiz. Quyidagi misolda Mockito yordamida simulatsiya qilingan xizmat e'lon qilingan:

<bean id="accountService" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="org.example.AccountService"/>
</bean>

Keyin siz simulatsiya qilingan xizmatni testga kiritishingiz mumkin, shunda testni sozlash va kutilgan natijalaringizni tekshirish mumkin bo'ladi, quyidagi misolda ko'rsatilgandek:

Java
@SpringJUnitWebConfig(locations = "test-servlet-context.xml")
class AccountTests {
    @Autowired
    AccountService accountService;
    MockMvc mockMvc;
    @BeforeEach
    void setup(WebApplicationContext wac) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }
    // ...
}
Kotlin
@SpringJUnitWebConfig(locations = ["test-servlet-context.xml"])
class AccountTests {
    @Autowired
    lateinit var accountService: AccountService
    lateinit mockMvc: MockMvc
    @BeforeEach
    fun setup(wac: WebApplicationContext) {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
    }
    // ...
}

Boshqa tomondan, standaloneSetup sozlash ko'proq modul testlariga mos keladi. U bir vaqtning o'zida bitta controllerni sinov etadi. Siz controllerda simulatsiya qilingan bog'liqliklarni qo'lda kiritishingiz mumkin va bu Spring konfiguratsiyasini yuklashni talab qilmaydi. Bunday testlar uslubga ko'proq qaratilgan va qaysi controller testlanayotganini, qandaydir maxsus Spring MVC konfiguratsiyasi kerakmi yoki yo'qligini aniqlashga yordam beradi. standaloneSetup sozlash ish mantig'ini tekshirish yoki biror muammo muhokamasi uchun maxsus testlar yozish uchun juda qulay usul hisoblanadi.

"Integratsiya testi va modul testi" mavzusidagi aksariyat bahslardagi kabi, bu erda ham to'g'ri yoki noto'g'ri javob yo'q. Biroq, standaloneSetup dan foydalanish Spring MVC konfiguratsiyasini tekshirish uchun webAppContextSetup dan ishlatishni talab etadi. Bundan tashqari, barcha testlarni webAppContextSetup bilan yozish, har doim haqiqiy Spring MVC konfiguratsiyasida test o'tkazishni ta'minlaydi.

Sozlashning xususiyatlari

MockMvc'dan qaysi qurilish vositasidan foydalanishingizdan qat'i nazar, barcha MockMvcBuilder realizatsiyalari umumiy va juda foydali xususiyatlarni taqdim etadi. Misol uchun, barcha so'rovlarda Accept sarlavhasini e'lon qilishingiz va 200 statusini qabul qilishingiz, shuningdek, barcha javoblarda Content-Type sarlavhasini kiritishingiz mumkin, quyida ko'rsatilgandek:

Java
// statik import MockMvcBuilders.standaloneSetup
MockMvc mockMvc = standaloneSetup(new MusicController())
    .defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
    .alwaysExpect(status().isOk())
    .alwaysExpect(content().contentType("application/json;charset=UTF-8"))
    .build();
Kotlin
// Kotlin'da mumkin emas, qachonki tuza qilingan bo'lsa

Bundan tashqari, uchinchi tomon framework'lari (va dasturlari) oldindan sozlash yo'riqnomalarini, masalan, MockMvcConfigurer da oldindan paketlangan qilib berishi mumkin. Spring Frameworkning bunday ichki realizatsiyalaridan biri HTTP sessiyani barcha so'rovlarda saqlash va qayta ishlatishga yordam beradi. Uni quyida ko'rsatilgandek ishlatishingiz mumkin:

Java
// statik import SharedHttpSessionConfigurer.sharedHttpSession
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
        .apply(sharedHttpSession())
        .build();
// So'rovlarni bajarish uchun mockMvc ni import qilish...
Kotlin
// Kotlin'da mumkin emas, qachonki tuza qilingan bo'lsa

ConfigurableMockMvcBuilder haqida javadoc ni ko'rib chiqing yoki mavjud opitsiyalarni o'rganish uchun IDE dan foydalaning.

So'rovlarni bajarish

Ushbu bo'limda MockMvc'ni alohida so'rovlarni bajarish va javoblarni tekshirish uchun qanday ishlatishni ko'rsatadi. Agar siz MockMvc'ni WebTestClient orqali ishlatayotgan bo'lsangiz, tegishli bo'limga murojaat qiling.

HTTP har qanday metodidan foydalanishga mo'ljallangan so'rovlarni WebTestClient yordamida qanday bajarishni quyidagi misolda ko'rsatilgan:

Java
// statik import MockMvcRequestBuilders.*.
mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));
Kotlin
import org.springframework.test.web.servlet.post
mockMvc.post("/hotels/{id}", 42) {
    accept = MediaType.APPLICATION_JSON
}

Shuningdek, yuklab olish fayllariga so'rovlarni bajarishingiz mumkin, ular ichki ravishda multipart so'rovni tahlil qilishni amalga oshirmasdan MockMultipartHttpServletRequest ni ishlatadi. Buning o'rniga, uni quyidagi misolda ko'rsatilgandek sozlashingiz kerak bo'ladi:

Java
mockMvc.perform(multipart("/doc").file("a1", "ABC".getBytes("UTF-8")));
Kotlin
import org.springframework.test.web.servlet.multipart
mockMvc.multipart("/doc") {
    file("a1", "ABC".toByteArray(charset("UTF8")))
}

So'rov parametrlari URI identifikatori shabloni uslubida quyida ko'rsatilgandek berilishi mumkin:

Java
mockMvc.perform(get("/hotels?thing={thing}", "somewhere"));
Kotlin
mockMvc.get("/hotels?thing={thing}", "somewhere")

Shuningdek, servlet so'rov parametrlari qo'shilishi mumkin, bu parametrlar ya'ni so'rov parametrlari yoki form parametrlaridir, quyidagi misolda ko'rsatilgandek:

Java
mockMvc.perform(get("/hotels").param("thing", "somewhere"));
Kotlin
import org.springframework.test.web.servlet.get
mockMvc.get("/hotels") {
    param("thing", "somewhere")
}

Agar ilova kodi servlet so'rov parametrlari va so'rov satrini aniqlamoqchi bo'lmasa (bu eng ko'p sodir bo'ladigan holat), unda qaysi variantni ishlatishingiz muhim emas. Biroq, esda tutingki, shlyuz URI identifikatori orqali berilgan so'rov parametrlari dekodlanadi, lekin param(…) metodi orqali berilgan so'rov parametrlari dekodlangan holida kutiladi.

Ko'pgina holatlarda so'rov URI identifikatoriga kontekst yo'li va servlet yo'lini qo'shmaslik tavsiya etiladi. Agar to'liq so'rov URI identifikatori bilan test o'tkazishni talab qilsangiz, so'rovlar mos kelishini ta'minlash uchun contextPath va servletPath ni mos ravishda o'tkazish esingizda bo'lsin, quyidagi misolda ko'rsatilgandek:

Java
mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main"))
Kotlin
import org.springframework.test.web.servlet.get
mockMvc.get("/app/main/hotels/{id}") {
    contextPath = "/app"
    servletPath = "/main"
}

Yuqorida ko'rsatilgan misolda contextPath va servletPath ni har bir bajarilgan so'rovda o'rnatish qiyin bo'ladi. Buning o'rniga, quyida ko'rsatilgandek, so'rovning standart xususiyatlarini o'rnatishingiz mumkin:

Java
class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup() {
        mockMvc = standaloneSetup(new AccountController())
            .defaultRequest(get("/")
            .contextPath("/app").servletPath("/main")
            .accept(MediaType.APPLICATION_JSON)).build();
    }
}
Kotlin
// Kotlin'da mumkin emas, qachonki tuza qilingan bo'lsa

Oldingi xususiyatlar MockMvc orqali bajarilgan har bir so'rovga ta'sir qiladi. Agar ushbu xususiyat ayni so'rovda ham ko'rsatilgan bo'lsa, u standart qiymatni almashtiradi. Shuning uchun so'rovning metodi va URI identifikatori muhim emas, chunki har bir so'rov uchun ularni ko'rsatishingiz kerak bo'ladi.

Kutilgan natijalarni aniqlash

Kutilgan natijalarni aniqlash uchun so'rov bajarilgandan so'ng bir yoki bir nechta andExpect(..) chaqiruvlarini qo'shishingiz mumkin, quyidagi misolda ko'rsatilgandek. Agar biror bir kutilgan natija sodir bo'lmasa, boshqa kutilgan natijalar tasdiqlanmaydi.

Java
// statik import MockMvcRequestBuilders.*. va MockMvcResultMatchers.*
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
Kotlin
import org.springframework.test.web.servlet.get
mockMvc.get("/accounts/1").andExpect {
    status { isOk() }
}

Birinchi kategoriya javob xususiyatlarini tekshiradi (masalan, javob statusi, sarlavhalar va mazmun). Bu eng muhim natijalar bo'lib, tasdiqlanishi mumkin bo'lgan natijalardir.

Ikkinchi kategoriya esa javobdan tashqariga chiqib ketadi. Bular Spring MVC'ning maxsus qirralarini tekshirish imkonini beradi, masalan, so'rov qaysi controller methodi tomonidan qayta ishlanganini, qaysi istisno chaqirilgan va qayta ishlanganini, model yig'indisi qanday ekanligini, qaysi ko'rinish tanlanganini, qaysi flash atributlar qo'shilganini va hokazo. Shuningdek, servlet'ning maxsus qirralarini, masalan, so'rov va sessiya atributlarini ham tekshirish imkoniyatini beradi.

Quyidagi test bog'lanish yoki validatsiya muvaffaqiyatsizlikka uchraganligini tasdiqlaydi:

Java
mockMvc.perform(post("/persons"))
    .andExpect(status().isOk())
    .andExpect(model().attributeHasErrors("person"));
Kotlin
import org.springframework.test.web.servlet.post
mockMvc.post("/persons").andExpect {
    status { isOk() }
    model {
        attributeHasErrors("person")
    }
}

Testlarni yozishda ko'pincha bajarilgan so'rov natijasini chiqarish foydali bo'ladi. Buni quyidagi usulda amalga oshirishingiz mumkin, bu erda print() - MockMvcResultHandlers dan statik kiritiladigan element hisoblanadi:

Java
mockMvc.perform(post("/persons"))
    .andDo(print())
    .andExpect(status().isOk())
    .andExpect(model().attributeHasErrors("person"));
Kotlin
import org.springframework.test.web.servlet.post
mockMvc.post("/persons").andDo {
        print()
    }.andExpect {
        status { isOk() }
        model {
            attributeHasErrors("person")
        }
    }

So'rovni qayta ishlashda qayta ko'rib chiqilmagan istisno chaqirilgunga qadar, print() metodi mavjud barcha natija ma'lumotlarini System.out ga chiqaradi. Shu bilan birga log() metodi va print() metodining ikki qo'shimcha variantlari mavjud, biri OutputStream ni qabul qiladi, ikkinchisi esa - Writer. Masalan, print(System.err) chaqirig'i natijani System.err ga chiqaradi, print(myWriter) chaqirig'i esa natijani maxsus yozuv (writer) metodiga chiqaradi. Agar natija ma'lumotlari chiqarilmasdan yozuvga qo'yilishi kerak bo'lsa, log() metodini chaqirishingiz mumkin, bu metodi natijani DEBUG xabari sifatida org.springframework.test.web.servlet.result jurnal kategoriyasida yozadi.

Ba'zi hollarda siz natijaga to'g'ridan-to'g'ri kirishni xohlashingiz va boshqa yo'l bilan tekshirilishi mumkin bo'lmagan ma'lumotlarni tekshirishingiz kerak bo'ladi. Bu .andReturn() ni barcha boshqa kutilgan natijalarning orqasidan qo'shish orqali amalga oshiriladi, quyidagi misolda ko'rsatilgandek:

Java
MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn();
// ...
Kotlin
var mvcResult = mockMvc.post("/persons").andExpect { status { isOk() } }.andReturn()
// ...

Agar barcha testlar bir xil kutilgan natijalarni takrorlaydigan bo'lsa, MockMvc nusxasini yaratishda umumiy kutilgan natijalarni bir marta o'rnatishingiz mumkin, quyidagi misolda ko'rsatilgandek:

Java
standaloneSetup(new SimpleController())
    .alwaysExpect(status().isOk())
    .alwaysExpect(content().contentType("application/json;charset=UTF-8"))
    .build()
Kotlin
// Kotlin'da mumkin emas, qachonki tuza qilingan bo'lsa

Umumiy kutilgan natijalar har doim qo'llaniladi va MockMvc ning alohida nusxasini yaratmasdan qayta belgilanmaydi.

Agar JSON javobi mazmuni Spring HATEOAS orqali yaratilgan havolalarni o'z ichiga olsa, quyidagi misolda ko'rsatilgandek, JsonPath ifodalari orqali olingan havolalarni tekshirishingiz mumkin:

Java
mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON))
    .andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:8080/people"));
Kotlin
mockMvc.get("/people") {
    accept(MediaType.APPLICATION_JSON)
}.andExpect {
    jsonPath("$.links[?(@.rel == 'self')].href") {
        value("http://localhost:8080/people")
    }
}

Agar XML javobi mazmuni Spring HATEOAS orqali yaratilgan havolalarni o'z ichiga olsa, quyidagi misolda ko'rsatilgandek, XPath ifodalari orqali olingan havolalarni tekshirishingiz mumkin:

Java
Map<String, String> ns = Collections.singletonMap("ns", "http://www.w3.org/2005/Atom");
mockMvc.perform(get("/handle").accept(MediaType.APPLICATION_XML))
    .andExpect(xpath("/person/ns:link[@rel='self']/@href", ns).string("http://localhost:8080/people"));
Kotlin
val ns = mapOf("ns" to "http://www.w3.org/2005/Atom")
mockMvc.get("/handle") {
    accept(MediaType.APPLICATION_XML)
}.andExpect {
    xpath("/person/ns:link[@rel='self']/@href", ns) {
        string("http://localhost:8080/people")
    }
}

Asinxron so'rovlar

Ushbu bo'limda MockMvc'ni asinxron so'rovlarni sinashda qanday ishlatishni ko'rsatadi. Agar siz MockMvc'ni WebTestClient orqali ishlatayotgan bo'lsangiz, asinxron so'rovlarni bajarishda hech qanday alohida maxsus narsa yo'q, chunki WebTestClient avtomatik ravishda bu bo'limda tasvirlangan narsalarni amalga oshiradi.

Asinxron so'rovlar Servlet 3.0, Spring MVC'da qo'llab-quvvatlanadigan, servlet konteynerlari ipidan chiqish orqali ishlaydi, shunday qilib ilovaga javobni asinxron hisoblash imkonini beradi. So'ngra asinxron dispatch amalga oshiriladi va servlet konteynerlari ipida qayta ishlash tugatiladi.

Spring MVC Test'da asinxron so'rovlarni test qilish uchun avval ishlab chiqarilgan asinxron qiymatni tasdiqlab, so'ngra asinxron dispatchni qo'lda amalga oshirib va nihoyat javobni tekshirish kerak. Quyida DeferredResult, Callable yoki Reactor'dan Mono kabi reaktiv turlarni qaytaruvchi controller metodlari uchun test misoli keltiriladi:

Java
// statik import MockMvcRequestBuilders.*. va MockMvcResultMatchers.*
@Test
void test() throws Exception {
    MvcResult mvcResult = this.mockMvc.perform(get("/path"))
            .andExpect(status().isOk()) 
            .andExpect(request().asyncStarted()) 
            .andExpect(request().asyncResult("body")) 
            .andReturn();
    this.mockMvc.perform(asyncDispatch(mvcResult)) 
            .andExpect(status().isOk()) 
            .andExpect(content().string("body"));
}
  1. Javobning statusini tekshirish o'zgarishsiz qoladi
  2. Asinxron qayta ishlash boshlanishi kerak
  3. Asinxron qayta ishlash natijasini kutamiz va tasdiqlaymiz
  4. Asinxron dispatchni qo'lda amalga oshiramiz (yurayotgan konteyner yo'q)
  5. So'nggi javobni tekshi
Kotlin
@Test
fun test() {
    var mvcResult = mockMvc.get("/path").andExpect {
        status { isOk() } 
        request { asyncStarted() } 
        // TODO Qo'llanilmagan geneerik parametrni olib tashlang
        request { asyncResult<Nothing>("body") } 
    }.andReturn()
    mockMvc.perform(asyncDispatch(mvcResult)) 
            .andExpect {
                status { isOk() } 
                content().string("body")
            }
}
  1. Javobning statusini tasdiqlash o'zgarishsiz qoladi
  2. Asinxron qayta ishlash boshlanishi kerak
  3. Asinxron qayta ishlash natijasini kutamiz va tasdiqlaymiz
  4. Asinxron dispatchni qo'lda amalga oshiramiz (ishlayotgan konteyner yo'q)
  5. So'nggi javobni tekshiramiz

Stream javoblar

Stream javoblarni, masalan, serverdan yuborilgan voqealarni (Server-Sent Events) sinashning eng yaxshi usuli bu WebTestClient, qaysiki MockMvc misoliga testing o'tkazish uchun ulash mumkin, Spring MVC controller'larini ishlaydigan serversiz sinovlarni amalga oshirish uchun. Masalan:

Java
WebTestClient client = MockMvcWebTestClient.bindToController(new SseController()).build();
FluxExchangeResult<Person> exchangeResult = client.get()
        .uri("/persons")
        .exchange()
        .expectStatus().isOk()
        .expectHeader().contentType("text/event-stream")
        .returnResult(Person.class);
// Project Reactor'dan StepVerifier ishlatish Stream javobni sinovdan o'tkazish uchun
StepVerifier.create(exchangeResult.getResponseBody())
        .expectNext(new Person("N0"), new Person("N1"), new Person("N2"))
        .expectNextCount(4)
        .consumeNextWith(person -> assertThat(person.getName()).endsWith("7"))
        .thenCancel()
        .verify();

WebTestClient shuningdek haqiqiy serverga ulana oladi va to'liq skvoz integratsiya sinovlarini bajaradi. Bunday narsa Spring Boot'da ham qo'llab-quvvatlanadi, qaysi yerda siz ishlayotgan serverni sinash imkoniga ega bo'lasiz.

Filtrlarni ro'yxatdan o'tkazish

MockMvc misolini sozlashda bir yoki bir nechta servlet Filter nusxalarini ro'yxatdan o'tkazishingiz mumkin, quyidagiga o'xshash:

Java
mockMvc = standaloneSetup(new PersonController()).addFilters(new CharacterEncodingFilter()).build();
Kotlin
// Kotlin'da mumkin emas, qachonki tuza qilingan bo'lsa

Ro'yxatdan o'tkazilgan filtrlar spring-test dan MockFilterChain orqali chaqiriladi, va oxirgi filtra DispatcherServlet ga delegat qiladi.

MockMvc va skvoz testlar

MockMvc spring-test modulidagi Servlet API taqlid qilingan realizatsiyalari asosida qurilgan va ishlayotgan konteynerga bog'liq emas. Shuning uchun, haqiqiy klient va haqiqiy server bilan to'liq skvoz integratsiya testlari bilan ba'zi farqlar mavjud.

Buni tushunishning eng oddiy usuli bo'sh MockHttpServletRequest so'rovini boshlashdir. Unga necha narsa qo'shsangiz, bu so'rovga aylanadi. Sizni ajablanishi mumkin bo'lgan narsalar: odatda kontekst yo'llari mavjud emas, jsessionid cookie fayli yo'q, qayta yo'naltirish yo'q, xatoliklar yoki asinxron dispetch, bu orqali shu nuqtada JSP render (vizualizatsiya) yo'q. Buning o'rniga "qayta yo'naltirilgan" va "readdresslangan" URL manzillari MockHttpServletResponse da saqlanib qoladi, so'ngra kutilgan natijalar bilan tasdiqlanishi mumkin.

Bu demak, agar JSP ishlatilayotgani bo'lsa, qayta yo'naltirilgan JSP sahifasini tekshirishingiz mumkin, lekin HTML render qilinmaydi. Boshqacha aytganda, JSP chaqirilmaydi. Biroq, boshqa render texnologiyalari, masalan, Thymeleaf va Freemarker, HTML ni javob tanasiga yetkazadi, kutilgani kabi. O'smir JSON, XML va boshqa formatlar render qilishda ham shunday holat @ResponseBody bilan izohlangan metodlar yordamida amalga oshiriladi.

Bundan tashqari, @SpringBootTest annotatsiyasi bilan to'liq skvoz integratsion testlarni o'tkazish uchun Spring Boot tomonidan qo'llab-quvvatlanadigan imkoniyatlar haqida o'ylab ko'ring. Buni ko'ring Spring Boot Qo'llanma Qo'llanmasi.

Har bir yondashuv o'zining foydali va noqulay tomonlariga ega. Spring MVC Testda taqdim etilgan opitsiyalar klassik modul testdan to'liq integratsion test darajasiga o'zgartirilgan usullarni o'z ichiga oladi. Albatta, Spring MVC Testdagi opitsiyalarning hech biri klassik modul test kategoriyasiga tushmaydi, lekin ular unga yaqinroq. Masalan, simulatsiya qilingan xizmatlarni controller'ga kiritib, veb darajasini boshqa darajalardan ajratib olinib test qilish mumkin, va bu holatda veb darajasi faqat DispatcherServlet orqali sinovdan o'tkaziladi, lekin haqiqiy Spring konfiguratsiyasi bilan, chunki ma'lumotlarga kirish darajasini mustaqil tekshirish mumkin bo'ladi. Shuningdek, mustaqil sozlashni ishlatib, bir vaqtning o'zida bitta controller'ga e'tibor berib, ishlashi uchun zarur bo'lgan konfiguratsiyani qo'lda ta'minlash mumkin.

Spring MVC Test framework'da test qilishda yana bir muhim farq shundaki, bunday testlar server tomonli bo'lib, siz qaysi handler ishlatilganini, istisno qanday qilib HandlerExceptionResolver yordamida qayta ishlanganini, model mazmuni qanday ekanligini, qanday bog'lanish xatoliklari bo'lganini va boshqa ma'lumotlarni tekshirish imkoniga egasiz. Bu kutilgan natijalarni yozishni osonlashtiradi, chunki server shaffof quti emas, haqiqiy HTTP klient orqali test o'tkazilganda bo'lgani kabi. Umuman olganda, klassik modul testining afzalligi shundaki, bunday testlarni yozish, asoslash va tuzatish osonroq, lekin u to'liq integratsion testlarga ehtiyojni bekor qilmaydi. Shu bilan birga, javob eng muhim narsa ekanligini tekshirishni unutmaslik muhimdir. Bitta loyiha doirasida ham bir nechta uslub va test strategiyasiga imkoniyat beradigan kenglik mavjud.

Qo'shimcha misollar

Framework o'z testlari bir qator test misollar ni ichiga oladi, ular MockMvc alohida yoki WebTestClient orqali qanday ishlatilishini ko'rsatishga mo'ljallangan. Ushbu misollarni ko'rib chiqing va yangi g'oyalarni oling.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION