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