Spring学习之旅(十)--MockMvc
在之前的 Spring學習之旅(八)--SpringMVC請求參數 我們是通過在控制臺輸出來驗證參數是否正確,但是這樣做實在是太耗時間了,我們今天來學習下 MockMvc,它可以讓我們不需要啟動項目就能調用接口并驗證接口返回結果是否符合我們的預期。
為何使用MockMvc?
MockMvc 實現了對 Http 請求的模擬,能夠直接使用網絡的形式,實現 Controller 的調用,這樣可以使得測試速度快、不依賴網絡環境,而且提供了一套驗證的工具,這樣可以使得請求的驗證統一而且很方便。
如何使用 MockMvc
MockMvcBuilder 是用來構造 MockMvc 的構造器,主要有兩個實現:
StandaloneMockMvcBuilder
DefaultMockMvcBuilder
分別對應兩種測試方式,即獨立安裝和集成 Web 環境測試(此種方式并不會集成真正的 web 環境,而是通過相應的 Mock API 進行模擬測試,無須啟動服務器)。對于我們來說直接使用靜態工廠 MockMvcBuilders 創建即可。
集成Web環境方式
MockMvcBuilders.webAppContextSetup(WebApplicationContext context) :指定 WebApplicationContext,將會從該上下文獲取相應的控制器并得到相應的 MockMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
@WebAppConfiguration
public class RequestParameterControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
}
獨立測試方式
MockMvcBuilders.standaloneSetup(Object... controllers) :通過參數指定一組控制器,這樣就不需要從上下文獲取了;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
@WebAppConfiguration
public class RequestParameterControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new RequestParameterController()).build();
}
}
實例
Controller:
@Controller
public class RequestParameterController {
@RequestMapping("/toInt")
@ResponseBody
public int toInt(int value) {
return value;
}
}
單元測試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
@WebAppConfiguration
public class RequestParameterControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void toInt() throws Exception {
mockMvc.perform(
// 發送 GET 請求
MockMvcRequestBuilders.get("/toInteger?value=3"))
// 判斷HTTP響應碼
.andExpect(MockMvcResultMatchers.status().isOk())
// 判斷返回內容是否是預期值
.andExpect(MockMvcResultMatchers.content().string("3"))
// 輸出整個響應結果信息
.andDo(MockMvcResultHandlers.print());
}
}
控制臺輸出:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /toInteger
Parameters = {value=[3]}
Headers = {}
Handler:
Type = com.marklogzhu.web.controller.RequestParameterController
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[1]}
Content type = text/plain;charset=ISO-8859-1
Body = 3
Forwarded URL = null
Redirected URL = null
Cookies = []
Process finished with exit code 0
常用對象
MockMvcRequestBuilders
MockMvcRequestBuilders: 用來構建請求。
| 方法 | 作用 |
|---|---|
| MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables) | 發送 GET 請求 |
| MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables) | 發送 POST 請求 |
| MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables) | 發送 PUT 請求 |
| MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) | 發送 DELETE 請求 |
| MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables) | 發送 OPTIONS 請求 |
| MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) | 提供自己的Http請求方法及uri模板和uri變量 |
| MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables) | 發送文件上傳請求 |
| RequestBuilder asyncDispatch(final MvcResult mvcResult) | 創建一個啟動異步處理的請求的 MvcResult 進行異步分派的RequestBuilder |
ResultActions
調用 MockMvc.perform(RequestBuilder requestBuilder) 后將得到 ResultActions,通過 ResultActions 可以完成如下三件事:
ResultActions andExpect(ResultMatcher matcher) :添加驗證斷言來判斷執行請求后的結果是否是預期的;
ResultActions andDo(ResultHandler handler) :添加結果處理器,用于對驗證成功后執行的動作,如輸出下請求/結果信息用于調試;
MvcResult andReturn() :返回驗證成功后的MvcResult;用于自定義驗證/下一步的異步處理;
ResultMatcher
| 方法 | 作用 |
|---|---|
| HandlerResultMatchers handler() | 請求的 Handler 驗證器,比如驗證處理器類型/方法名;此處的 Handler 其實就是處理請求的控制器 |
| RequestResultMatchers request() | 得到 RequestResultMatchers 驗證器 |
| ModelResultMatchers model() | 得到模型驗證器 |
| ViewResultMatchers view() | 得到視圖驗證器 |
| FlashAttributeResultMatchers flash() | 得到 Flash 屬性驗證 |
| StatusResultMatchers status() | 得到響應狀態驗證器 |
| HeaderResultMatchers header() | 得到響應 Header 驗證器 |
| CookieResultMatchers cookie() | 得到響應 Cookie 驗證器 |
| ContentResultMatchers content() | 得到響應內容驗證器 |
| JsonPathResultMatchers jsonPath(String expression, Object ... args) | 得到Json表達式驗證器 |
| ResultMatcher jsonPath(String expression, Matcher matcher) | 得到Json表達式驗證器 |
| XpathResultMatchers xpath(String expression, Object... args) | 得到Xpath表達式驗證器 |
| XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args) | 得到Xpath表達式驗證器 |
| ResultMatcher forwardedUrl(final String expectedUrl) | 驗證處理完請求后轉發的url(絕對匹配) |
| ResultMatcher forwardedUrlPattern(final String urlPattern) | 驗證處理完請求后轉發的url(Ant風格模式匹配,@since spring4) |
| ResultMatcher redirectedUrl(final String expectedUrl) | 驗證處理完請求后重定向的url(絕對匹配) |
| ResultMatcher redirectedUrlPattern(final String expectedUrl) | 驗證處理完請求后重定向的url(Ant風格模式匹配,@since spring4) |
實例
JSON請求/響應驗證
String requestBody = "{"id":1, "name":"zhang"}";
mockMvc.perform(post("/user")
.contentType(MediaType.APPLICATION_JSON).content(requestBody)
.accept(MediaType.APPLICATION_JSON)) //執行請求
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) //驗證響應contentType
.andExpect(jsonPath("$.id").value(1)); //使用Json path 驗證JSON,具體表達式規則請參考 http://goessner.net/articles/JsonPath/
String errorBody = "{id:1, name:zhang}";
MvcResult result = mockMvc.perform(post("/user")
.contentType(MediaType.APPLICATION_JSON).content(errorBody)
.accept(MediaType.APPLICATION_JSON)) //執行請求
.andExpect(status().isBadRequest()) //400錯誤請求
.andReturn();
Assert.assertTrue(HttpMessageNotReadableException.class.isAssignableFrom(result.getResolvedException().getClass()));//錯誤的請求內容體
文件上傳
byte[] bytes = new byte[] {1, 2};
mockMvc.perform(fileUpload("/user/{id}/icon", 1L).file("icon", bytes)) //執行文件上傳
.andExpect(model().attribute("icon", bytes)) //驗證屬性相等性
.andExpect(view().name("success")); //驗證視圖
自定義驗證
MvcResult result = mockMvc.perform(get("/user/{id}", 1))//執行請求
.andReturn(); //返回MvcResult
Assert.assertNotNull(result.getModelAndView().getModel().get("user")); //自定義斷言
總結
以上是生活随笔為你收集整理的Spring学习之旅(十)--MockMvc的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见Web前端开发笔试题
- 下一篇: 【总结整理】高德LBS开放平台学习