Spring Boot 單元測試
一、使用mock進行單元測試
Spring框架提供了MockMvc物件,可以在服務端完成對Controller的啟動。測試開始之前需要建立測試環境,setup方法被@Before修飾。通過MockMvcBuilders工具,使用WebApplicationContext物件作為引數,建立一個MockMvc物件。
示例:
@RunWith(SpringRunner.class)
//這裡的CodedictCustomApplication是springboot的啟動類名
@SpringBootTest(classes = CodedictCustomApplication.class)
public class CodeDictControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mvc;
@Before
public void setupMockMvc(){
//初始化MockMvc物件
mvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
/**
* mockMvc.perform執行一個請求
* MockMvcRequestBuilders.get(“/user/1”)構造一個請求,Post請求就用.post方法
* contentType(MediaType.APPLICATION_JSON_UTF8)代表傳送端傳送的資料格式是application/json;charset=UTF-8
* accept(MediaType.APPLICATION_JSON_UTF8)代表客戶端希望接受的資料型別為application/json;charset=UTF-8
* ResultActions.andExpect新增執行完成後的斷言
* ResultActions.andExpect(MockMvcResultMatchers.status().isOk())方法看請求的狀態響應碼是否為200如果不是則拋異常,測試不通過
* ResultActions.andExpect(MockMvcResultMatchers.jsonPath("$.showValue").value("證件型別")),這裡jsonPath用來獲取showValue欄位比對是否為證件型別,不是就測試不通過
* ResultActions.andDo新增一個結果處理器,表示要對結果做點什麼事情,比如此處使用MockMvcResultHandlers.print()輸出整個響應結果資訊
* @throws Exception
*/
@Test
public void getAllCatalog() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/getAllCatalog")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
@Test
public void getItem() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/getItem")
.param("rid","ZJLX")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.showValue").value("證件型別"))
.andExpect(MockMvcResultMatchers.jsonPath("$.catalogId").value("#"))
.andDo(MockMvcResultHandlers.print());
}
@Test
// 單元測試的時候如果不想造成垃圾資料,可以開啟事物功能,記在方法或者類頭部新增@Transactional註解即可
@Transactional
public void modifyItem()throws Exception{
mvc.perform(MockMvcRequestBuilders.get("/modifyItem")
.param("rid","ZJLX")
.param("code","ZJLX")
.param("catalogId","#")
.param("sortValue","1")
.param("showValue","證件")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
mvc.perform(MockMvcRequestBuilders.get("/getItem")
.param("rid","ZJLX")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.showValue").value("證件"))
.andExpect(MockMvcResultMatchers.jsonPath("$.sortValue").value("1"))
.andDo(MockMvcResultHandlers.print());
}
}
二、新斷言assertThat使用
JUnit 4.4 結合 Hamcrest 提供了一個全新的斷言語法——assertThat。程式設計師可以只使用 assertThat 一個斷言語句,結合 Hamcrest 提供的匹配符,就可以表達全部的測試思想,我們引入的版本是Junit4.12所以支援assertThat。
基本的語法:
assertThat( [value], [matcher statement] );
- value:是接下來想要測試的變數值;
- matcher statement:是使用 Hamcrest 匹配符來表達的對前面變數所期望的值的宣告,如果 value 值與 matcher statement 所表達的期望值相符,則測試成功,否則測試失敗。
示例:
@Test
public void assertThatUse(){
//1.使用匹配符 Matcher 和不使用之間的比較
// 想判斷某個字串 s 是否含有子字串 "developer" 或 "Works" 中間的一個
// JUnit 4.4 以前的版本:assertTrue(s.indexOf("developer")>-1||s.indexOf("Works")>-1 );
// JUnit 4.4:
assertThat("s",anyOf(containsString("developer"), containsString("Works")));
// 匹配符 anyOf 表示任何一個條件滿足則成立,類似於邏輯或 "||", 匹配符 containsString 表示是否含有引數子
// 字串,文章接下來會對匹配符進行具體介紹
//2.Matcher 匹配符聯合使用
// 聯合匹配符not和equalTo表示“不等於”
assertThat( "s", not( equalTo( "developer" )));
// 聯合匹配符not和containsString表示“不包含子字串”
assertThat( "s", not( containsString( "Works")));
// 聯合匹配符anyOf和containsString表示“包含任何一個子字串”
assertThat("s", anyOf(containsString("developer"), containsString("Works")));
//3.預設提供一些可讀的描述性錯誤資訊
String s = "hello world!";
assertThat( s, anyOf( containsString("developer"), containsString("Works") ) );
// 如果出錯後,系統會自動丟擲以下提示資訊:
// java.lang.AssertionError:
// Expected: (a string containing "developer" or a string containing "Works")
// but: was "s"
// Expected :(a string containing "developer" or a string containing "Works")
}
其它使用示例:
字元相關匹配符
/**equalTo匹配符斷言被測的testedValue等於expectedValue,
* equalTo可以斷言數值之間,字串之間和物件之間是否相等,相當於Object的equals方法
*/
assertThat(testedValue, equalTo(expectedValue));
/**equalToIgnoringCase匹配符斷言被測的字串testedString
*在忽略大小寫的情況下等於expectedString
*/
assertThat(testedString, equalToIgnoringCase(expectedString));
/**equalToIgnoringWhiteSpace匹配符斷言被測的字串testedString
*在忽略頭尾的任意個空格的情況下等於expectedString,
*注意:字串中的空格不能被忽略
*/
assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);
/**containsString匹配符斷言被測的字串testedString包含子字串subString**/
assertThat(testedString, containsString(subString) );
/**endsWith匹配符斷言被測的字串testedString以子字串suffix結尾*/
assertThat(testedString, endsWith(suffix));
/**startsWith匹配符斷言被測的字串testedString以子字串prefix開始*/
assertThat(testedString, startsWith(prefix));
一般匹配符
/**nullValue()匹配符斷言被測object的值為null*/
assertThat(object,nullValue());
/**notNullValue()匹配符斷言被測object的值不為null*/
assertThat(object,notNullValue());
/**is匹配符斷言被測的object等於後面給出匹配表示式*/
assertThat(testedString, is(equalTo(expectedValue)));
/**is匹配符簡寫應用之一,is(equalTo(x))的簡寫,斷言testedValue等於expectedValue*/
assertThat(testedValue, is(expectedValue));
/**is匹配符簡寫應用之二,is(instanceOf(SomeClass.class))的簡寫,
*斷言testedObject為Cheddar的例項
*/
assertThat(testedObject, is(Cheddar.class));
/**not匹配符和is匹配符正好相反,斷言被測的object不等於後面給出的object*/
assertThat(testedString, not(expectedString));
/**allOf匹配符斷言符合所有條件,相當於“與”(&&)*/
assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );
/**anyOf匹配符斷言符合條件之一,相當於“或”(||)*/
assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );
數值相關匹配符
/**closeTo匹配符斷言被測的浮點型數testedDouble在20.0¡À0.5範圍之內*/
assertThat(testedDouble, closeTo( 20.0, 0.5 ));
/**greaterThan匹配符斷言被測的數值testedNumber大於16.0*/
assertThat(testedNumber, greaterThan(16.0));
/** lessThan匹配符斷言被測的數值testedNumber小於16.0*/
assertThat(testedNumber, lessThan (16.0));
/** greaterThanOrEqualTo匹配符斷言被測的數值testedNumber大於等於16.0*/
assertThat(testedNumber, greaterThanOrEqualTo (16.0));
/** lessThanOrEqualTo匹配符斷言被測的testedNumber小於等於16.0*/
assertThat(testedNumber, lessThanOrEqualTo (16.0));
集合相關匹配符
/**hasEntry匹配符斷言被測的Map物件mapObject含有一個鍵值為"key"對應元素值為"value"的Entry項*/
assertThat(mapObject, hasEntry("key", "value" ) );
/**hasItem匹配符表明被測的迭代物件iterableObject含有元素element項則測試通過*/
assertThat(iterableObject, hasItem (element));
/** hasKey匹配符斷言被測的Map物件mapObject含有鍵值“key”*/
assertThat(mapObject, hasKey ("key"));
/** hasValue匹配符斷言被測的Map物件mapObject含有元素值value*/
assertThat(mapObject, hasValue(value));
相關文章
- Spring Boot乾貨系列:(十二)Spring Boot使用單元測試Spring Boot
- 使用 Spring Boot 進行單元測試Spring Boot
- Mokito 單元測試與 Spring-Boot 整合測試Springboot
- Spring Boot單元和整合測試概述 | rieckpilSpring BootKPI
- Spring Boot單元測試之服務層測試總結Spring Boot
- Spring Boot之單元測試用例總結Spring Boot
- Spring Boot之DAO層的單元測試小結Spring Boot
- 怎樣使用Spring Boot專案的單元測試Spring Boot
- 怎樣使用Spring Boot專案的單元測試?Spring Boot
- 如何建立自己的Spring Boot Starter併為其編寫單元測試Spring Boot
- Spring AOP單元測試綜合指南Spring
- Spring Boot(十二):Spring Boot 如何測試打包部署Spring Boot
- 測試 之Java單元測試、Android單元測試JavaAndroid
- 單元測試:單元測試中的mockMock
- 021-Spring Boot 測試Spring Boot
- Spring Boot 中測試 CORSSpring BootCORS
- Spring單元測試教程(JUnit5+Mockito)SpringMockito
- 如何在spring環境中做單元測試Spring
- 單元測試,只是測試嗎?
- 單元測試-【轉】論單元測試的重要性
- SpringBoot單元測試Spring Boot
- python 單元測試Python
- iOS 單元測試iOS
- Flutter 單元測試Flutter
- 單元測試 Convey
- 單元測試真
- golang單元測試Golang
- 單元測試工具
- 前端單元測試前端
- 十五、單元測試
- Go單元測試Go
- 聊聊單元測試
- 前端測試:Part II (單元測試)前端
- 單元測試提速,使用上一次 spring 資源Spring
- 如何對Spring MVC中的Controller進行單元測試SpringMVCController
- Spring入門學習手冊 4:Spring單元測試怎麼搞?Spring
- Spring、Spring Boot和TestNG測試指南 – 整合測試中用Docker建立資料庫Spring BootDocker資料庫
- Spring Boot中用嵌入式PostgreSQL測試Spring BootSQL