Spring Webflux и Spring Web — это два совершенно разных веб-стека. Однако Spring Webflux продолжает поддерживать модель программирования на основе аннотаций.
Конечная точка, определенная с использованием этих двух стеков, может выглядеть одинаково, но способ проверки такой конечной точки довольно различен, и пользователь, пишущий такую конечную точку, должен знать, какой стек является активным, и соответствующим образом сформулировать тест.
Пример конечной точки
Рассмотрим пример конечной точки на основе аннотации:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.web.bind.annotation.PostMapping</span> import org.springframework.web.bind.annotation.PostMapping</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.web.bind.annotation.RequestBody</span> import org.springframework.web.bind.annotation.RequestBody</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.web.bind.annotation.RequestMapping</span> import org.springframework.web.bind.annotation.RequestMapping</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.web.bind.annotation.RestController</span> import org.springframework.web.bind.annotation.RestController</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >data class Greeting(val message: String)</span> класс данных Greeting (val message: String)</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @RestController </span> @RestController </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @RequestMapping ( "/web" )</span> @RequestMapping ( "/ веб" )</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > class GreetingController {</span> class GreetingController {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @PostMapping ( "/greet" )</span> @PostMapping ( "/" ) Greet</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >fun handleGreeting( @RequestBody greeting: Greeting): Greeting {</span> fun handleGreeting ( @RequestBodyreeting : Greeting): Приветствие {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > return Greeting( "Thanks: ${greeting.message}" )</span> return Greeting ( "Спасибо: $ {reeting.message}" )</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> |
Тестирование с помощью Spring Web
Если для создания этого приложения использовался стартер Spring Boot 2 с Spring Web в качестве стартера, это указывается с помощью файла сборки Gradle следующим образом:
1
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >compile( 'org.springframework.boot:spring-boot-starter-web' )</span> компиляции ( 'org.springframework.boot: весна-загрузка-стартер-сеть' )</span> |
тогда проверка такой конечной точки будет использовать Mock Web Runtime, называемую Mock MVC :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.junit.Test</span> импорт org.junit.Test</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.junit.runner.RunWith</span> import org.junit.runner.RunWith</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.beans.factory.annotation.Autowired</span> import org.springframework.beans.factory.annotation.Autowired</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest</span> import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.context.junit4.SpringRunner</span> import org.springframework.test.context.junit4.SpringRunner</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.web.servlet.MockMvc</span> import org.springframework.test.web.servlet.MockMvc</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post</span> import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content</span> import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @RunWith (SpringRunner:: class )</span> @RunWith (SpringRunner :: класс)</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @WebMvcTest (GreetingController:: class )</span> @WebMvcTest (GreetingController :: класс)</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > class GreetingControllerMockMvcTest {</span> class GreetingControllerMockMvcTest {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @Autowired </span> @Autowired </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >lateinit var mockMvc: MockMvc</span> lateinit var mockMvc: MockMvc</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @Test </span> @Тест</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >fun testHandleGreetings() {</span> fun testHandleGreetings () {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >mockMvc</span> mockMvc</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.perform(</span> .Произвести (</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >post( "/web/greet" )</span> пост ( "/ веб / Greet" )</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.content( "" "</span> .content ( " "»</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|{</span> | {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >| "message" : "Hello Web" </span> | "message" : "Hello Web" </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|}</span> |}</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "" ".trimMargin())</span> " "».TrimMargin ())</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >).andExpect(content().json( "" "</span> ) .AndExpect (содержание (). JSON ( " "»</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|{</span> | {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >| "message" : "Thanks: Hello Web" </span> | "message" : "Спасибо: Hello Web" </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|}</span> |}</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "" ".trimMargin()))</span> " "».TrimMargin ()))</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> |
Тестирование с помощью Spring Web-Flux
Если, с другой стороны, стартеры Spring-Webflux были задействованы, скажем, со следующей зависимостью Gradle:
1
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >compile( 'org.springframework.boot:spring-boot-starter-webflux' )</span> компиляции ( 'org.springframework.boot: весна-загрузки-стартер-webflux' )</span> |
тогда тест этой конечной точки будет использовать отличный класс WebTestClient , а именно:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.junit.Test</span> импорт org.junit.Test</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.junit.runner.RunWith</span> import org.junit.runner.RunWith</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.beans.factory.annotation.Autowired</span> import org.springframework.beans.factory.annotation.Autowired</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest</span> import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.http.HttpHeaders</span> import org.springframework.http.HttpHeaders</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.context.junit4.SpringRunner</span> import org.springframework.test.context.junit4.SpringRunner</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.test.web.reactive.server.WebTestClient</span> import org.springframework.test.web.reactive.server.WebTestClient</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > import org.springframework.web.reactive.function.BodyInserters</span> import org.springframework.web.reactive.function.BodyInserters</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @RunWith (SpringRunner:: class )</span> @RunWith (SpringRunner :: класс)</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @WebFluxTest (GreetingController:: class )</span> @WebFluxTest (GreetingController :: класс)</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > class GreetingControllerTest {</span> class GreetingControllerTest {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @Autowired </span> @Autowired </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >lateinit var webTestClient: WebTestClient</span> lateinit var webTestClient: WebTestClient</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > @Test </span> @Тест</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >fun testHandleGreetings() {</span> fun testHandleGreetings () {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >webTestClient.post()</span> webTestClient.post ()</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.uri( "/web/greet" )</span> .uri ( "/ веб / Greet" )</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.header(HttpHeaders.CONTENT_TYPE, "application/json" )</span> .header (HttpHeaders.CONTENT_TYPE, "application / json" )</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.body(BodyInserters</span> .Body (BodyInserters</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.fromObject( "" "</span> .fromObject ( " "»</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|{</span> | {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|</span> |</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "message" : "Hello Web" </span> "message" : "Hello Web" </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|}</span> |}</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "" ".trimMargin()))</span> " "».TrimMargin ()))</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.exchange()</span> .exchange ()</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.expectStatus().isOk</span> .expectStatus (). isOk</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.expectBody()</span> .expectBody ()</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >.json( "" "</span> .json ( " "»</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|{</span> | {</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|</span> |</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "message" : "Thanks: Hello Web" </span> "message" : "Спасибо: Hello Web" </span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >|}</span> |}</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" > "" ".trimMargin())</span> " "».TrimMargin ())</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> <span class = "notranslate" onmouseover= "_tipon(this)" onmouseout= "_tipoff()" ><span class = "google-src-text" style= "direction: ltr; text-align: left" >}</span> }</span> |
Вывод
Легко предположить, что, поскольку модель программирования выглядит очень похожей при использовании стеков Spring Web и Spring Webflux, тесты для такого унаследованного теста с использованием Spring Web продолжались бы до Spring Webflux, однако это не так, поскольку у нас есть разработчик помнить о базовом стеке, который вступает в игру, и формулировать тест соответствующим образом. Я надеюсь, что этот пост проясняет, как такой тест должен быть обработан.
Смотрите оригинальную статью здесь: Аннотированные контроллеры — Spring Web / Webflux и Тестирование
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |