Spring Webflux对比Spring Web有何优点

原创于 【模棱博客】

Spring Webflux和Spring Web是两个完全不同的Web栈。 然而, Spring Webflux继续支持基于注解的编程模型

使用这两个堆栈定义的端点可能看起来相似,但测试这种端点的方式是相当不同的,写这样一个端点的用户必须知道哪个堆栈处于活动状态并据此制定测试。

样品端点

考虑一个基于示例注释的端点:

import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController


data class Greeting(val message: String)

@RestController
@RequestMapping("/web")
class GreetingController {
    
    @PostMapping("/greet")
    fun handleGreeting(@RequestBody greeting: Greeting): Greeting {
        return Greeting("Thanks: ${greeting.message}")
    }
    
}

 

使用Spring Web进行测试

如果Spring Boot 2启动器用于使用Spring Web作为启动器创建此应用程序,则按以下方式使用Gradle构建文件指定:

 

compile('org.springframework.boot:spring-boot-starter-web')

 

那么这样一个端点的测试将会使用一个Mock web运行时,被称为Mock MVC :

import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content


@RunWith(SpringRunner::class)
@WebMvcTest(GreetingController::class)
class GreetingControllerMockMvcTest {

    @Autowired
    lateinit var mockMvc: MockMvc

    @Test
    fun testHandleGreetings() {
        mockMvc
                .perform(
                        post("/web/greet")
                                .content(""" 
                                |{
                                |"message": "Hello Web"
                                |}
                            """.trimMargin())
                ).andExpect(content().json("""
                    |{
                    |"message": "Thanks: Hello Web"
                    |}
                """.trimMargin()))
    }
}

 

使用Spring Web-Flux进行测试

另一方面,如果Spring-Webflux初学者被拉入,比如说下面的Gradle依赖关系:

 

compile('org.springframework.boot:spring-boot-starter-webflux')

 

那么这个端点的测试将使用优秀的WebTestClient类,沿着这些线:

import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest
import org.springframework.http.HttpHeaders
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.web.reactive.function.BodyInserters


@RunWith(SpringRunner::class)
@WebFluxTest(GreetingController::class)
class GreetingControllerTest {

    @Autowired
    lateinit var webTestClient: WebTestClient

    @Test
    fun testHandleGreetings() {
        webTestClient.post()
                .uri("/web/greet")
                .header(HttpHeaders.CONTENT_TYPE, "application/json")
                .body(BodyInserters
                        .fromObject(""" 
                                |{
                                |   "message": "Hello Web"
                                |}
                            """.trimMargin()))
                .exchange()
                .expectStatus().isOk
                .expectBody()
                .json("""
                    |{
                    |   "message": "Thanks: Hello Web"
                    |}
                """.trimMargin())
    }
}

 

结论

很容易假设,因为使用Spring Web和Spring Webflux堆栈的编程模型看起来非常相似,使用Spring Web进行这种传统测试的测试将继续到Spring Webflux,但事实并非如此,因为我们的开发人员注意潜在的堆栈,并据此制定测试。 我希望这篇文章能够阐明如何制定这样的测试。

原创于 【模棱博客】

 http://www.flammulina.com/2018/03/31/vs-spring-webflux对比spring-web/

你可能感兴趣的:(VS)