Rest接口單元測試


Get請求url不超過4000字節
Rest成熟度:level 0:使用http作為傳輸方式,leve 1:引入資源概念,每個資源有對應的url,level 2:使用http方法進行不同操作,使用http狀態碼表示不同結果,level 3:使用超媒體,在資源表達式中包含鏈接信息,一般做到level 2
測試依賴:org.springframework.boot:spring-boot-starter-test
測試類:
package com.example.security ;
import org.junit. Before ;
import org.junit.runner. RunWith ;
import org.springframework.beans.factory.annotation. Autowired ;
import org.springframework.boot.test.context. SpringBootTest ;
import org.springframework.test.context.junit4.SpringRunner ;
import org.springframework.test.web.servlet.MockMvc ;
import org.springframework.test.web.servlet.setup.MockMvcBuilders ;
import org.springframework.web.context.WebApplicationContext ;
@RunWith (SpringRunner. class ) //使用SpringRunner運行
@SpringBootTest //表明這是一個測試用例
public class SecurityApplicationTests {
@Autowired
private WebApplicationContext wac ; //注入web環境,但是並不會啟動Tomcat,所以很快
private MockMvc mockMvc ; //模擬web環境
@Before //@Before會在每個@Test之前執行,在里面初始化模擬的web環境
public void setup () {
mockMvc = MockMvcBuilders. webAppContextSetup ( wac ).build() ;
}
}
Rest請求單元測試舉例(推薦先寫好測試用例,執行,失敗紅色,然后去寫Rest api,過程中不斷執行測試用例,直到測試用例通過):
@Test
public void queryUsersOK () throws Exception {
mockMvc .perform(MockMvcRequestBuilders. get ( "/users" )
.contentType(MediaType. APPLICATION_JSON_UTF8 ))
.andExpect(MockMvcResultMatchers. status ().isOk())
.andExpect(MockMvcResultMatchers. jsonPath ( "$.length()" ).value( 2 )) ;
}
該測試用例向/users發送get請求,contentType為 application/json;charset=UTF-8 ,期望響應狀態碼200,期望響應json字符串數組長度為2。其中jsonPath是用來解析響應的json。 請求格式錯誤會報400。請求的method不匹配會報405。
這里的$代表返回的json文檔,具體可在github搜索jsonPath第一個項目json-path/JsonPath即可,具體使用參考 https://github.com/json-path/JsonPath的Operators和Functions(方法)

注:測試用例中MockMvcRequestBuilders和MockMvcResultMatchers兩個靜態類常用,可以添加到STS的偏好設置,菜單欄Preferences--Java--Editor--Content Assist--Favorites--New Type(直接在Preferences搜索fa即可)
添加到偏好設置以后,自動變成靜態引用,代碼簡化:
//靜態引用
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders. get ;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. jsonPath ;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. status ;
//測試用例
@Test
public void queryByParam () throws Exception {
String result = mockMvc .perform( get ( "/user" )
// .param("username", "wangzhongshan")
// .param("password", "kibana")
.contentType(MediaType. APPLICATION_JSON_UTF8 ))
.andExpect( status ().isOk())
// .andExpect(jsonPath("$.length()").value(1));
.andExpect( jsonPath ( "$username" ).value( "wzs" ))  //斷言返回json對象的屬性的值
.andReturn().getResponse().getContentAsString() //獲取響應的字符串值
}
若要傳遞參數,如圖注釋,添加一到多個.param(String key, String value)即可,生成/user?key=value的查詢,后台可用同名參數或對象的同名屬性接受之,無論后台接受參數/參數對象屬性是什么類型,測試用例的param之value都傳字符串類型。
單元測試執行技巧:在@Test方法上執行run,先執行@Before方法再執行@Test方法,在空白位置執行run,所有@Test都會執行(每個@Test執行之前都會執行@Before),在package上執行run,則包下面所有的測試類的@Test都將執行
常用注解:
@RestController,@RequestMapping及變體(如@GetMapping,其源碼可知是被@RequestMapping注解了並指定了相應的method)
@RequestParam(參數require默認true,必傳,value是name屬性的別名,兩個都是給參數指定名字)
@PathVariable(映射url片段到參數,屬性require默認true,必填,value是name屬性的別名。url聲明 可以使用正則表達式,如@RequestMapping(value = "/user/{id:\\d+}")規范id只能傳整數,否則報400
新學注解: @PageableDefault指定分頁參數默認值(rest api傳輸類建包DTO)
org.springframework.data.domain.Pageable(Spring Data提供)
controller可使用該對象接受page,size,sort(排序,值如age,desc)三個分頁參數值,也可以在用@PageableDefault注解Pageable對象,其提供page,size,sort這3個屬性給Pageable提供默認值,代碼:
@RequestMapping ( "/users" )
public List<User> users ( @PageableDefault ( page = 0 , size = 10 , sort = "username, asc" ) Pageable page) {
page.getPageNumber() ;
page.getPageSize() ;
page.getSort() ;
return new ArrayList<>() ;
}
post請求:參數為json對象,映射到controller方法的參數對象必須要用@RequestBody注解,否則json參數無法映射到參數對象,參數的屬性只能拿到Null。
測試用例(post攜帶content傳參):
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders. post ;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders. put ;
@Test
public void createUser () throws Exception {
String content = "{ \" username \" : \" test \" , \" pasword \" : \" 123456 \" , \" date \" :" + System. currentTimeMillis ()+ "}" ;
String result = mockMvc .perform( post ( "/user" ).contentType(MediaType. APPLICATION_JSON_UTF8 ).content(content)) //put與post的測試用例寫法相同,只是把post改成put,url改成如/usr/1
.andExpect( status ().isOk()).andExpect( jsonPath ( "$.id" ).value( "1" ))
.andReturn().getResponse().getContentAsString() ;
System. out .println(result) ; //時間屬性,向后台傳參是System.currentTImeMillis();,返回的是 2019-08-24T04:06:49.154+0000
}
如果參數對象有Date屬性,可以用yyyy-MM-dd或yyyy-MM-dd HH:mm:ss等時間格式字符串轉換,但是需要轉換且需要適配不同的展示格式,因此直接在json中傳遞時間戳(毫秒值)更方便,入庫存時間戳,前台展示什么樣式由js控制。前台時間戳和后台Date類型能夠自由轉換(經測試,從瀏覽器url傳的date=時間戳轉換失敗)。
刪除單元測試(請求方法使用多了,直接引用*即可):
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* ;
@Test
public void deleteUser () throws Exception {
mockMvc .perform( delete ( "/user/1" ).contentType(MediaType. APPLICATION_JSON_UTF8 )).andExpect( status ().isOk()) ;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM