1 <!-- Spring和MVC的包這裏不列出來了,webmvc,aspects,orm,其餘maven會自動導 --> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>4.9</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>org.springframework</groupId> 10 <artifactId>spring-test</artifactId> 11 <version> 4.1.3.RELEASE</version> 12 <scope>provided</scope> 13 </dependency>
一、控制器例子java
1 package henu.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.ResponseBody; 6 7 import henu.entity.Exam; 8 9 /** 10 * @ClassName: MockTestController <br/> 11 * @Describtion: Mock框架測試用例. <br/> 12 * @date: 2018年4月19日 下午2:02:47 <br/> 13 * @author Beats <br/> 14 * @version v1.0 15 */ 16 @Controller 17 public class MockTestController { 18 19 @RequestMapping("/hello") 20 @ResponseBody 21 public String hello(String hello) { 22 return hello + " world!"; 23 } 24 25 @RequestMapping("/json") 26 @ResponseBody 27 public Exam json(String json) { 28 Exam e = new Exam(); 29 e.setId(123); 30 e.setSubject(json); 31 return e; 32 } }
二、測試例子web
1 package henu.test; 2 3 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload; 4 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 5 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 6 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; 7 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 8 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; 9 10 import javax.annotation.Resource; 11 12 import org.junit.Before; 13 import org.junit.Test; 14 import org.junit.runner.RunWith; 15 import org.springframework.http.MediaType; 16 import org.springframework.test.context.ContextConfiguration; 17 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 18 import org.springframework.test.context.transaction.TransactionConfiguration; 19 import org.springframework.test.context.web.WebAppConfiguration; 20 import org.springframework.test.web.servlet.MockMvc; 21 import org.springframework.test.web.servlet.setup.MockMvcBuilders; 22 import org.springframework.transaction.annotation.Transactional; 23 import org.springframework.web.context.WebApplicationContext; 24 25 /** 26 * @ClassName: TestMock <br/> 27 * @Describtion: 使用Spring集成的Mock框架測試web應用的控制器. <br/> 28 * @date: 2018年4月19日 下午1:58:22 <br/> 29 * @author Beats <br/> 30 * @version v1.0 31 */ 32 //這個必須使用junit4.9以上纔有 33 @RunWith(SpringJUnit4ClassRunner.class) 34 //單元測試的時候真實的開啓一個web服務,測試完畢就關閉 35 @WebAppConfiguration 36 //配置事務的回滾,對數據庫的增刪改都會回滾,便於測試用例的循環利用 37 @TransactionConfiguration(transactionManager="txManager", defaultRollback=true) 38 @Transactional 39 @ContextConfiguration(locations={"classpath:spring.xml","classpath:springmvc.xml"}) 40 //@ContextConfiguration(locations="classpath:spring*.xml") 41 public class TestMock { 42 43 /** 44 * web應用的上下文 45 */ 46 @Resource 47 private WebApplicationContext context; 48 /** 49 * Mock框架的核心類 50 */ 51 private MockMvc mockMVC; 52 53 @Before 54 public void initMockMVC() { 55 this.mockMVC = MockMvcBuilders.webAppContextSetup(context).build(); 56 } 57 58 @Test 59 public void testStringResult() throws Exception{ 60 61 String res = mockMVC.perform(get("/hello") 62 .param("hello", "This is my") 63 .contentType(MediaType.TEXT_HTML) 64 .accept(MediaType.TEXT_HTML)) 65 .andExpect(status().isOk())//指望值 66 .andDo(print())//打印結果 67 .andReturn().getResponse().getContentAsString();//結果字符串 68 System.err.println(res); 69 70 } 71 72 @Test 73 public void testJsonResult() throws Exception{ 74 75 String res = mockMVC.perform(get("/json") 76 .param("json", "JAVA") 77 .param("hah", "hah") 78 //請求參數的類型 79 .contentType(MediaType.TEXT_HTML) 80 //但願服務器返回的值類型 81 .accept(MediaType.APPLICATION_JSON)) 82 .andExpect(status().isOk())//指望值 83 .andDo(print())//打印結果 84 .andReturn().getResponse().getContentAsString();//結果字符串 85 System.err.println(res); 86 } 87 88 @Test 89 public void testModelResult() throws Exception{ 90 91 String res = mockMVC.perform(get("/json") 92 .param("json", "JAVA") 93 .param("hah", "hah") 94 //請求參數的類型 95 .contentType(MediaType.TEXT_HTML) 96 //但願服務器返回的值類型 97 .accept(MediaType.APPLICATION_JSON)) 98 .andExpect(status().isOk())//指望值 99 .andDo(print())//打印結果 100 .andReturn().getResponse().getContentAsString();//結果字符串 101 System.err.println(res); 102 } 103 104 @Test 105 public void testOthers() throws Exception { 106 byte[] bytes = new byte[] {1, 2}; 107 mockMVC.perform( 108 fileUpload("/user/{id}/icon", 1L).file("icon", bytes)) //執行文件上傳 109 .andExpect(model().attribute("icon", bytes)) //驗證屬性相等性 110 .andExpect(view().name("success")); //驗證視圖 111 112 // mockMvc.perform(post("/user").param("name", "zhang")) //執行傳遞參數的POST請求(也能夠post("/user?name=zhang")) 113 // .andExpect(handler().handlerType(UserController.class)) //驗證執行的控制器類型 114 // .andExpect(handler().methodName("create")) //驗證執行的控制器方法名 115 // .andExpect(model().hasNoErrors()) //驗證頁面沒有錯誤 116 // .andExpect(flash().attributeExists("success")) //驗證存在flash屬性 117 // .andExpect(view().name("redirect:/user")); //驗證視圖 118 } 119 }
1 /** 2 * perform:執行一個RequestBuilder請求,會自動執行SpringMVC的流程並映射到相應的控制器執行處理; 3 * get:聲明發送一個get請求的方法。MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根據uri模板和uri變量值獲得一個GET請求方式的。另外提供了其餘的請求的方法,如:post、put、delete等。 4 * param:添加request的參數,如上面發送請求的時候帶上了了pcode = root的參數。假如使用須要發送json數據格式的時將不能使用這種方式 5 * andExpect:添加ResultMatcher驗證規則,驗證控制器執行完成後結果是否正確(對返回的數據進行的判斷); 6 * andDo:添加ResultHandler結果處理器,好比調試時打印結果到控制檯(對返回的數據進行的判斷); 7 * andReturn:最後返回相應的MvcResult;而後進行自定義驗證/進行下一步的異步處理(對返回的數據進行的判斷) 8 */
注意上面contentType須要設置成MediaType.APPLICATION_JSON,即聲明是發送「application/json」格式的數據。使用content方法,將轉換的json數據放到request的body中。
在spring開發中,可使用Spring自帶的MockMvc這個類進行Mock測試。spring
所謂的Mock測試,這裏我舉一個通俗易懂的例子,像servlet API中的HttpServletRequest對象是Tomcat容器生成的。咱們沒法手動的new出來,因而就有了所謂的Mock測試數據庫
用到的註解:json
1 mockMvc = webAppContextSetup(wac) 2 .defaultRequest(get("/user/1").requestAttr("default", true)) //默認請求 若是其是Mergeable類型的,會自動合併的哦mockMvc.perform中的RequestBuilder 3 .alwaysDo(print()) //默認每次執行請求後都作的動做 4 .alwaysExpect(request().attribute("default", true)) //默認每次執行後進行驗證的斷言 5 .build(); 6 7 mockMvc.perform(get("/user/1")) 8 .andExpect(model().attributeExists("user"));