通常,在我們平時開發項目時,如果想要輸入URL對Controller進行測試,在代碼編輯之后,需要重啟服務器,建立http client進行測試。這樣會使得測試變得很麻煩,比如,啟動速度慢,測試驗證不方便,依賴網絡環境等,這樣會導致測試無法進行,為了可以對Controller進行測試,可以通過引入MockMVC進行解決。
MockMvc實現了對Http請求的模擬,能夠直接使用網絡的形式,轉換到Controller的調用,這樣可以使得測試速度快、不依賴網絡環境,而且提供了一套驗證的工具,這樣可以使得請求的驗證統一而且很方便。
MockMvcBuilder是用來構造MockMvc的構造器,其主要有兩個實現:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分別對應兩種測試方式,即獨立安裝和集成Web環境測試(此種方式並不會集成真正的web環境,而是通過相應的Mock API進行模擬測試,無須啟動服務器)。對於我們來說直接使用靜態工廠MockMvcBuilders創建即可。
下面就寫幾個簡單的案例,使用MockMvc測試Controller中的get請求和post請求。
1.引入jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
2.編寫測試controller
/**
* @author Sue
* @create 2019-09-06 10:03
**/
@RestController
@RequestMapping("/mock")
public class MockmvcController {
/**
* get請求
* @param username
* @param password
* @return
*/
@GetMapping("/getInfo")
public R getInfo(String username,String password){
System.out.println("username:" + username + "," + "password:" + password);
return R.ok();
}
/**
* post請求
* @param username
* @param password
* @return
*/
@PostMapping("/getInfo2")
public R getInfo2(String username,String password){
System.out.println("username:" + username + "," + "password:" + password);
return R.ok();
}
/**
* post請求接收json格式
* @param user
* @return
*/
@PostMapping("/getInfo3")
public R getInfo3(@RequestBody User user){
System.out.println(user);
return R.ok(user);
}
}
3.創建單元測試
idea使用快捷鍵ctrl+alt+t
@RunWith(SpringRunner.class)
@SpringBootTest
public class MockmvcTest {
// 注入web環境的ApplicationContext容器
@Autowired
private WebApplicationContext context;
/**
* 模擬mvc測試對象
*/
private MockMvc mockMvc;
/**
* 所有測試方法執行之前執行該方法
*/
@Before // 這個注解的作用,在每個方法之前都會執行一遍
public void before() throws Exception {
//獲取mockmvc對象實例
mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void getInfo() throws Exception {
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.get("/mock/getInfo")
.param("username", "Jack")
.param("password", "Jack001"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()).andReturn();
System.out.println("輸出 " + mvcResult.getResponse().getContentAsString());
}
@Test
public void getInfo2() throws Exception {
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/mock/getInfo2")
.accept(MediaType.APPLICATION_JSON)
.param("username", "Jack")
.param("password", "Jack001"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()).andReturn();
System.out.println("輸出 " + mvcResult.getResponse().getContentAsString());
}
@Test
public void getInfo3() throws Exception {
User user = new User();
user.setUsername("Jack");
user.setPassword("Jack001");
String jsonString = JSON.toJSONString(user);
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/mock/getInfo3")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()).andReturn();
int status = mvcResult.getResponse().getStatus();
Assert.assertTrue("正確", status == 200);
System.out.println("輸出 " + mvcResult.getResponse().getContentAsString());
}
}
4.測試
代碼解析 :
perform:執行一個RequestBuider請求,自動執行SpringMvc的流程並映射到相應的控制器執行處理get: 聲明一個發送get請求的方法.public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) { return new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars);}這是個靜態方法,可以直接導入,根據uri模版和uri的變量值得到一個get請求的方法. 另外提供了其他的請求方法, 如:post、put、delete等.andExperct: 添加ResultMatcher驗證規則,驗證perform執行完成后的結果是否正確(對返回的數據進行判斷)andDo: 添加ResultHandler結果處理器,比如調試打印結果到控制台print()andReturn: 最后返回相應的MvcResult,然后進行自定義驗證/進行下一步的異步處理.
整個測試過程如下:
1、准備測試環境
2、通過MockMvc執行請求
3、添加驗證斷言
4、添加結果處理器
5、得到MvcResult進行自定義斷言/進行下一步的異步請求
6、卸載測試環境
通過這幾個方法,相信大家對mockMvc測試有了一些了解,如果想要使用更多細節,通過方法名和參數應該也能看懂方法含義,如果還是不能理解,可以查看下面的官方文檔配合使用。
