基於Spring-WS的Restful API的集成測試

在不少Java企業級應用中,Spring佔據了很是重要的位置,這就致使了基本上的技術選型都是圍繞着Spring來, 比方說筆者最近的項目須要開發一個Restful的API接口,選型的時候就說,客戶架構師直接就拍了spring-ws,緣由呢?系統中其餘的模塊都是用的Spring-ws,保持一致,並且社區活躍,文檔豐富,遇到問題易解決。好了,入正題。

既然選定了Spring-WS, 已經TDD入魔的我,首先想到的就是我應該怎麼測試這個API接口呢? 做爲業界最成熟的框架,Spring爲測試其Web應用提供了很是好用的輔助類MockMvc。

首先,在項目的測試代碼中加入輔助Spring Web測試的庫 java

Gradle代碼   收藏代碼
  1. testCompile(  
  2.             "org.springframework:spring-test:$springVersion",  
  3.             "org.springframework.ws:spring-ws-test:2.1.0.RELEASE",  
  4.             "javax.servlet:javax.servlet-api:3.0.1",  
  5.             "com.jayway.jsonpath:json-path-assert:0.9.0"  
  6.     )  

其中,jsonpath庫的依賴是爲了更好的作json格式數據的斷言。

而後,編寫測試代碼 git

Java代碼   收藏代碼
  1. //指定使用SpringIntegration測試,而且制定了運行測試的ApplicationContext  
  2. @RunWith(SpringJUnit4ClassRunner.class)  
  3. @ContextConfiguration(locations = {"classpath:spring-servlet.xml"})  
  4. public class ApiControllerIntegrationTest {  
  5.   
  6.     @Autowired  
  7.     private ApiController controller;  
  8.   
  9.     private MockMvc mockMvc;  
  10.   
  11.     @Before  
  12.     public void setUp() throws Exception {  
  13.         //綁定須要測試的Controller到MockMvcshang  
  14.         mockMvc = MockMvcBuilders.standaloneSetup(controller).build();  
  15.     }  
  16.   
  17.     @Test  
  18.     public void testGet() throws Exception {  
  19.         //發出請求,在請求中能夠設置一個http request可設置的全部參數  
  20.         mockMvc.perform(get("/requests/1")  
  21.                 .contentType(MediaType.APPLICATION_JSON)  
  22.                 .accept(MediaType.APPLICATION_JSON)  
  23.                 .param("userId", "xianlinbox")  
  24.         )  
  25.         //驗證Respondse,status()中,可驗證全部的HTTP Status CODE  
  26.         //另外,使用了jsonPath更優雅的作json屬性值的驗證  
  27.                 .andExpect(status().isOk())  
  28.                 .andExpect(jsonPath("$.userId").value("xianlinbox"))  
  29.                 .andExpect(jsonPath("$.requestId").value("1"))  
  30.                 .andExpect(jsonPath("$.requestType").value("GET"));  
  31.     }  
  32.   
  33.     @Test  
  34.     public void testPost() throws Exception {  
  35.         mockMvc.perform(post("/requests")  
  36.                 .contentType(MediaType.APPLICATION_JSON)  
  37.                 .accept(MediaType.APPLICATION_JSON)  
  38.                 .content("this is the message")  
  39.                 .param("userId", "xianlinbox")  
  40.         )  
  41.                 //使用print()可打印出當前測試設計的HTTP Request/Responsed的全部信息,方便定位問題  
  42.                 //Post方法的返回結果應該是202(HttpStatus.Created),對象建立成功  
  43.                 .andDo(print())  
  44.                 .andExpect(status().isCreated())  
  45.                 .andExpect(jsonPath("$.userId").value("xianlinbox"))  
  46.                 .andExpect(jsonPath("$.requestType").value("POST"))  
  47.                 .andExpect(jsonPath("$.message").value("this is the message"));  
  48.     }  
  49.   
  50. }  


testPost方法中的print()語句打印出的效果以下:
MockHttpServletRequest:
         HTTP Method = POST
         Request URI = /requests
          Parameters = {userId=[xianlinbox]}
             Headers = {Content-Type=[application/json], Accept=[application/json]}

             Handler:
                Type = com.xianlinbox.api.ApiController
              Method = public com.xianlinbox.api.Request com.xianlinbox.api.ApiController.post(java.lang.String,java.lang.String)

               Async:
   Was async started = false
        Async result = null

  Resolved Exception:
                Type = null

        ModelAndView:
           View name = null
                View = null
               Model = null

            FlashMap:

MockHttpServletResponse:
              Status = 201
       Error message = null
             Headers = {Content-Type=[application/json;charset=UTF-8]}
        Content type = application/json;charset=UTF-8
                Body = {"userId":"xianlinbox","requestId":"1","requestType":"POST","message":"this is the message"}
       Forwarded URL = null
      Redirected URL = null
             Cookies = []

看完了測試, 來簡單的看下具體的實現代碼: github

Java代碼   收藏代碼
  1. @Controller  
  2. public class ApiController {  
  3.   
  4.     @RequestMapping(value = "/requests/{requestId}", method = RequestMethod.GET)  
  5.     @ResponseBody  
  6.     public Request get(@PathVariable String requestId, @RequestParam(value = "userId") String userId) {  
  7.         return new Request(userId, requestId, "GET");  
  8.     }  
  9.   
  10.     @RequestMapping(value = "/requests", method = RequestMethod.POST)  
  11.     @ResponseBody  
  12.     @ResponseStatus(value = HttpStatus.CREATED)  
  13.     public Request post(@RequestParam(value = "userId") String userId, @RequestBody String content) {  
  14.         Request request = new Request(userId, "1", "POST");  
  15.         request.setMessage(content);  
  16.         return request;  
  17.     }  
  18. }  

 

  • 使用RequestMapping定義URL
  • 使用@ResponseBody表示返回json
  • 使用@PathVariable 獲取路徑參數
  • 使用@RequestParam獲取request payload中的參數
  • 使用@RequestBody獲取request body
  • 使用@ResponseStatus(value = HttpStatus.CREATED),定義返回的HTTP STATUS CODE



該Demo的全部代碼: https://github.com/xianlinbox/TDD_Demo/tree/master/spring-ws-restspring

相關文章
相關標籤/搜索