1. 程式人生 > >Spring Boot常用測試場景及分析

Spring Boot常用測試場景及分析

1 常見測試場景

1.1 MVC測試單個Controller

可通過MockMvc進行特定MVC的請求測試處理;
要進行單個Controller的測試,需要使用@WebMvcTest來指定需要測試的Controller。
WebMvcTest及MockMvc的使用分析見後文。

import com.liuqi.learn.learninterceptor.controller.TestController
import org.junit.Test
import org.junit.runner.RunWith
import org.slf4j.LoggerFactory
import
org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.* import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import
org.springframework.test.web.servlet.result.MockMvcResultMatchers.* @RunWith(SpringRunner::class) @WebMvcTest(TestController::class) class LearninterceptorApplicationTests { private val logger = LoggerFactory.getLogger(LearninterceptorApplicationTests::class.java) @Autowired private lateinit var mvc: MockMvc @Test fun testTestController
() { mvc.perform(get("/test/test")).andExpect(status().isOk) .andExpect(content().string("test")); } }

1.2 MVC測試多個Controller

可以針對多個Controller進行測試,啟動的是同一個容器;
不需要指定待測試的Controller;
也可以通過MockMvc來啟動模擬請求;
示例如下: 

@RunWith(SpringRunner::class)
@SpringBootTest
@AutoConfigureMockMvc
class TestLearninterceptorApplication {
    @Autowired
    private lateinit var mvc: MockMvc

    @Test
    fun testTest() {
        mvc.perform(MockMvcRequestBuilders.get("/test/test")).andExpect(MockMvcResultMatchers.status().isOk)
                .andExpect(MockMvcResultMatchers.content().string("test"));
    }

    @Test
    fun testTest1() {
        mvc.perform(MockMvcRequestBuilders.get("/test2/test")).andExpect(MockMvcResultMatchers.status().isOk)
                .andExpect(MockMvcResultMatchers.content().string("test2"));
    }
}

1.3 測試打樁

可以通過MockBean進行測試打樁;
先看Service的定義: 

@Service
class TestService {
    fun test(): String {
        return "test"
    }
}

再看使用Service的Controller

@RestController
@RequestMapping("/test2")
class TestController2 {
    val logger = LoggerFactory.getLogger(TestController2::class.java)

    @Autowired
    private lateinit var testService: TestService

    @RequestMapping("/test")
    fun test(): String {
        logger.info("TestController2!")

        return "test2"
    }

    @RequestMapping("/service")
    fun testService(): String {
        return testService.test()
    }
}

最後編寫測試類: 

@SpringBootTest
@AutoConfigureMockMvc
class TestLearninterceptorApplication {
    @Autowired
    private lateinit var mvc: MockMvc

    @MockBean
    private lateinit var testService: TestService

    @Test
    fun testMock() {
        BDDMockito.given(this.testService.test()).willReturn("mockTest")
        mvc.perform(MockMvcRequestBuilders.get("/test/service")).andExpect(MockMvcResultMatchers.status().isOk)
                .andExpect(MockMvcResultMatchers.content().string("mockTest"))
    }
}

1.4 整合測試

可以通過TestRestTemplate來進行整合測試;即在應用已經部署並在測試環境啟動時,可以通過指定URL的方式進行測試用例的測試;
一般通過TestRestTemplate來進行測試(當然TestRestTemplate也可以進行單元測試,後文會進行詳細說明);

import org.hamcrest.CoreMatchers.*
import org.junit.Assert
import org.junit.Test
import org.springframework.boot.test.web.client.TestRestTemplate

class SITest {
    private val restTemplate: TestRestTemplate = TestRestTemplate()

    @Test
    fun testRest() {
        val body = restTemplate.getForEntity("http://localhost/test2/service", String::class.java).body
        Assert.assertThat(body, `is`("test"))
    }
}

2 常見測試類

2.1 WebMvcTest

與SpringRunner一起使用,可測試指定的Controller;
注意在使用時需要指定待測試的Controller,可以指定多個待測試的Controller;

@WebMvcTest(*[TestController::class, TestController2::class])

WebMvcTest一般用於單元測試中測試Controller及其生效的Filter等場景;他會啟動一個Spring容器,但只會載入其中部分MVC相關的內容,如Component、Service或者Repository等註解的Bean不會進行載入。
會載入的:Controller/ControllerAdvice/JsonComponent/Converter/Filter/WebMvcConfigurer/HandlerMethodArgumentResolver等; 因此如果待測試的Controller中使用瞭如Service等內容,需要打樁處理。
它所啟動的Spring容器將會隨測試用例的開始執行而啟動,隨所有測試用例執行完畢而停止;因此它適合本地開發環境的測試用例執行。

2.2 SpringBootTest

與SpringRunner一起使用,不需要指定Controller進行測試。
SpringBootTest會啟動一個完整的Spring容器,這意味著它會載入所有Spring的內容;類似於將應用部署到了測試環境的Tomcat中;
與WebMvcTest一樣,啟動的只是一個臨時的環境,隨著測試用例的執行而啟動,在所有測試用例執行完畢後這個環境會將會停止, 適合本地開發環境的測試用例執行。

2.3 TestRestTemplate

TestRestTemplate可使用在以下兩個場景的測試:

2.3.1 遠端測試

TestRestTemplate可用於Rest服務的遠端測試;針對的是應用已經部署在測試環境應用伺服器中的場景;
它可通過指定http://ip:port/…這種路徑的方式來訪問特定連結進行整合測試;

2.3.1 本地測試

TestRestTemplate也可用於本地開發環境的測試,與MockMvc類似,可通過指定相對路徑的方式呼叫本地啟動的SpringMVC來進行MVC測試;這種情況下也需要與SpringBootTest整合使用。
它與MockMVC不一樣的是,MockMVC只能針對返回的內容進行測試,而TestRestTemplate可對Body、Headers等進行測試;
使用方式如下: 

@RunWith(SpringRunner::class)
@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
class TestLearninterceptorApplication2 {
    @Autowired
    private lateinit var template: TestRestTemplate

    @Test
    fun test() {
        val body = template.getForEntity("/test2/service", String::class.java).body
        Assert.assertThat(body, CoreMatchers.`is`("test"))
    }

//    @TestConfiguration
//    class Config {
//        @Bean
//        fun restTemplateBuilder(): RestTemplateBuilder {
//            return RestTemplateBuilder()
//        }
//    }
}

注意如果在SpringBootTest中不指定埠,則會報TestRestTemplate無法注入的錯誤。
TestRestTemplate的常用方法介紹如下: 

方法名 說明
getForObject 通過Get方式請求並獲取返回資料
getForEntity 通過Get方式請求並獲取返回物件,返回物件型別為ResponseEntity
headForHeaders 獲取傳入URL的Headers,返回物件為HttpHeaders
postForLocation 通過Post方傳送請求,返回物件為URI
postForObject 通過POST方式請求並獲取返回資料
postForEntity 通過POST方式傳送請求並獲取返回物件,返回物件型別為ResponseEntity

部分場景下會返回ResponseEntity物件,該物件的常用方法如下: 

方法名 說明
getStatusCode 獲取請求返回的狀態碼,如404等
getHeaders 獲取請求返回的Headers
getBody 獲取請求返回的Body
hasBody 是否有返回Body

2.4 MockMvc

MockMvc用於對本地啟動的Spring環境進行測試,通過它的perform方法,它會模擬一個Http請求訪問SpringMVC並返回ResultActions物件;
它一般要與SpringBootTest或者是WebMvcTest一起使用;
MockMvc的使用主要是使用其perform方法,這個方法返回型別是ResultActions物件;
這個物件包含以下方法: 

方法 說明 使用
andExpect 判斷結果是否滿足某個ResultMatcher物件 mockMvc.perform(post(“/form”)).andExpect(status().isOk()).andExpect(redirectedUrl(“/person/1”))
andDo 針對結果做某種處理,如列印等; mockMvc.perform(get(“/form”)).andDo(print())
andReturn 返回MvcResult物件,可以獲取Request、Response以及返回的資料等資訊。

andExpect方法中的Matcher可以使用MockMvcResultMatchers來進行構建,其可構建的Matcher包括:

方法 說明
request 獲取RequestResultMatchers型別的Matcher,可對Attribute、SessionAttribute等進行判斷;
handler 獲取HandlerResultMatchers型別的Matcher,具體用法見該類定義
model 獲取ModelResultMatchers型別的Matcher,可對返回的資料物件進行判斷;
view 獲取ViewResultMatchers型別的Matcher,可對返回檢視的名稱進行判斷;
forwardedUrl 判斷返回的頁面連結是否符合預期
redirectedUrl 判斷跳轉的頁面連結是否符合預期
status 返回StatusResultMatchers物件,判斷請求狀態是否符合預期
header 返回HeaderResultMatchers物件,對返回的報文頭內容進行判定
content 返回ContentResultMatchers物件,對返回的Body內容進行判定

三者結構使用的示例見1.1章節

2.5 MockBean

MockBean用於打樁,一般與BDDMockito結合使用。
MockBean本身功能較簡單,主要是BDDMockito的使用。

2.6 BDDMockito

詳細請參考此文
用於替換被打樁的Bean中的指定方法;
其包含的常用方法如下:

2.6.1 given

替換被打樁的物件的指定方法;
使用方式如:

val result = BDDMockito.given(this.testService.test())

其返回的型別為:BDDMyOngoingStubbing,其包含有以下常用方法:
- willAnswer: 根據傳入引數定製返回結果;
- will: 與willAnswer類似
- willReturn: 定製直接的返回結果;
- willThrow: 定製將會丟擲的異常
使用方法如:

val result = BDDMockito.given(this.testService.test())
result.willReturn("test") 

表示將這個方法的返回替換成test字串。

2.6.2 then

請參考此文

3 其它

3.1 WebMvcTest與SpringBootTest

這兩個註解只能新增一個,如果混合使用會報錯: 

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class 

其區別在於:
WebMvcTest用於單元測試場景,需要指定待測試的Controller;他也會啟動一個Spring容器,但只會載入其中部分MVC相關的內容,如Component、Service或者Repository等註解的Bean不會進行載入。
會載入的:Controller/ControllerAdvice/JsonComponent/Converter/Filter/WebMvcConfigurer/HandlerMethodArgumentResolver等;
SpringBootTest:用於整合測試場景,不需要指定待測試的Controller;它會啟動一個完整的Spring容器,所有的Bean都會進行載入與初始化。

相關推薦

Spring Boot常用測試場景分析

1 常見測試場景 1.1 MVC測試單個Controller 可通過MockMvc進行特定MVC的請求測試處理; 要進行單個Controller的測試,需要使用@WebMvcTest來指定需要測試的Controller。 WebMvcTest

spring boot 常用註釋用法

@Service 註解該類為業務邏輯類由spring容器進行管理  @Transactional(readOnly = true) 指定預設的事務類別(只讀)  @CacheConfig 配置了spring內建快取來快取常用查詢資料 findAll() 方法一

Spring Boot常用註解總結

auto 基於 back rgs enable glob 裝配 內容 註意 Spring Boot常用註解總結 @RestController和@RequestMapping註解 @RestController註解,它繼承自@Controller註解。4.0之前的版本,Sp

spring boot常用註解

cati resource resp .profile ring isa selection cor 服務層 @EnableAutoConfiguration 啟動自動裝載:使用了這個註解之後,所有引入的jar的starters都會被自動註入。這個類的設計就是為start

Spring Boot常用配置

resource intellij runtime 默認 per context none splay 文件的 概述     本文主要寫了下Spring Boot的一些常用配置。 Spring Boot基本配置     入口類:         Sprin

spring boot常用註解使用小結

throws 配置文件 只需要 extends 開發者 valid In 需要 hex 1、@RestController和@RequestMapping註解   4.0重要的一個新的改進是@RestController註解,它繼承自@Controller註解。   4.0

spring boot 2.0 源碼分析(五)

pen div shutdown down etc messages servle started fec 在上一篇文章中我們詳細分析了spring boot是如何準備上下文環境的,今天我們來看一下run函數剩余的內容。還是先把run函數貼出來: /**

spring boot 統一返回資料全域性異常處理

記錄關於spring boot 統一返回資料及全域性異常處理的操作實現。 一、統一返回資料 1、定義一個超類:BaseResponseVo @Data @NoArgsConstructor public class BaseResponseVo{ protected Integer r

Spring Boot測試篇):SpringBoot 測試

SpringBoot 測試 測試是對於一個CodeMonkey來說很重要的,也是必須要掌握的一項技能,凡事自測。 在pom.xml加入相關依賴 引入SpringBoot Test,這個預設新建 SpringBoot 專案就會自帶jar包。 編寫測試類 專案啟動

spring boot 單元測試(附:單元測試斷言彙總)

Spring boot 單元測試: 常用的程式測試方法有: 1、直接通過在瀏覽器輸入網址訪問; 2、通過postman工具來測試; 3、通過編寫python指令碼來進行測試; 但這樣經常會一測就要測一整塊,相對單元測試來說定位問題比較麻煩,單元測試能幫助我們拆分方法,單獨測試

Spring Boot 常用配置以及自定義配置

原文地址:https://renguangli.com/articles/spring-boot-config Spring Boot 常用配置簡單介紹及使用 多環境配置 Spring Boot Profile 在 Spring Boot 中多環境配置檔名需要滿足 app

Spring-boot報錯集解決方案

*************************** 申請未能開始******************* ********  描述:  無法配置DataSource:未指定'url'屬性,也無法配置嵌入資料來源。  原因:無法確定合適的驅動程式類   &n

spring-boot(十二)spring-boot測試打包部署

有很多網友會時不時的問我,spring boot專案如何測試,如何部署,在生產中有什麼好的部署方案嗎?這篇文章就來介紹一下spring boot 如何開發、除錯、打包到最後的投產上線。   開發階段 單元測試 在開發階段的時候最重要的是單元測試了,springboot對單元

spring-boot常用註解

註解 常用註解 @RestController 控制器註解 @RequestParam 獲取url引數 ?name=value @RequestParam(value = "name",defaultValue = "張三") String name @Reques

Spring Boot 常用 Starter

Spring Boot 通過 Starter 來提供系統服務,Spring Boot 已經提供了一系列 Starter,也可以開發自己的 Starter。比如需要開發一個 Web 應用,只要在 pom.xml 中宣告一下即可。 <dependency> <group

Spring Boot單元測試&網路請求

實際開發中,Junit單元測試是必不可少的。在spring-boot 中可以通過測試模組(spring-boot-starter-test)快速使用單元測試功能。 開始 本示例在 spring boot 1.5.4 版本測試通過 1、pom.xml中新增配置spring-b

抓包工具charles-常用測試場景

一、準備工作 手機設定代理 連線wifi—代理—設為手動—填入charles所在電腦主機名(cmd--ipconfig)、埠號(8888)--確定   Charles設定埠號:proxy—proxy setting--8888--OK &

spring boot junit測試的時候報錯MockServerContainer does not support addEndpoint

在編寫junit測試spring boot專案的時候報錯MockServerContainer does not support addEndpoint  然自己在@SpringBootTest中加上SpringBootTest.WebEnvironment.RANDOM_PORT成功解決

詳解Spring Boot 配置載入順序屬性載入順序

先給大家介紹下spring boot 配置載入順序,具體內容如下所示: 使用 Spring Boot 會涉及到各種各樣的配置,如開發、測試、線上就至少 3 套配置資訊了。Spring Boot 可以輕鬆的幫助我們使用相同的程式碼就能使開發、測試、線上環境使用不同的配置。 在 Spring B

spring boot單元測試之druid NullPointException

最近在使用spring boot 對 Controller 進行單元測試時,發現 druid 竟然丟擲了空指標異常。原因是,使用了druid的監控,需要經過druid的 Filter 攔截器,但是spr