Spring MVC Test

作者:範宗雲 来源:原创 发布时间:2015-04-22 归档:spring-test

开发环境 : JDK 7 Maven 3 Tomcat 7 Junit 4.11 Spring 4.1.5 MySQL 5.5 Eclipse Luna
Controller
		    @Controller
			@RequestMapping("/employee")
			public class EmployeeController {
			
				@Autowired
				private EmployeeDao employeeDao;
				private static final String PAGE_RESULT = "home";
				
				@RequestMapping(value = "/list", method = GET)
				public String list(ModelMap model) {
					List<Employee> list = employeeDao.getAll();
					model.put("employeeList", list);
					return PAGE_RESULT;
				}
				
				@RequestMapping(value = "/save", method = GET)
				public String save(ModelMap model, Employee employee) {
					boolean result = employeeDao.save(employee);
					model.put("success", result);
					return PAGE_RESULT;
				}
				
				@RequestMapping(value = "/info/{employeeId:[1-9]\\d*}", method = GET)
				public String info(ModelMap model, @PathVariable Integer employeeId) {
					Employee employee = employeeDao.queryById(employeeId);
					model.put("employee", employee);
					return PAGE_RESULT;
				}
				
				@RequestMapping(value = "/json/save", method = POST)
				public @ResponseBody boolean save(@RequestBody Employee employee) {
					boolean result = employeeDao.save(employee);
					return result;
				}
				
				@RequestMapping(value = "/json/info/{employeeId:[1-9]\\d*}", method = POST)
				public @ResponseBody Employee info(@PathVariable Integer employeeId) {
					Employee employee = employeeDao.queryById(employeeId);
					return employee;
				}
				
			}
		    
普通处理方法测试
		    import org.junit.Before;
			import org.junit.Test;
			import org.junit.runner.RunWith;
			import org.lychie.model.Employee;
			import org.springframework.beans.factory.annotation.Autowired;
			import org.springframework.test.context.ContextConfiguration;
			import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
			import org.springframework.test.context.transaction.TransactionConfiguration;
			import org.springframework.test.context.web.WebAppConfiguration;
			import org.springframework.test.web.servlet.MockMvc;
			import org.springframework.test.web.servlet.setup.MockMvcBuilders;
			import org.springframework.transaction.annotation.Transactional;
			import org.springframework.web.context.WebApplicationContext;
			import static org.hamcrest.Matchers.*;
			import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
			import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
			import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
			
			@RunWith(SpringJUnit4ClassRunner.class)
			@Transactional
			@TransactionConfiguration(defaultRollback = false)
			@WebAppConfiguration
			@ContextConfiguration({"/spring-context.xml", "/spring-mvc.xml"})
			public class EmployeeControllerTest {
			
				private MockMvc mockMvc;
				
				@Autowired
				private WebApplicationContext context;
				
				@Before
				public void setUp() {
					mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
				}
				
				@Test
				public void testList() throws Exception {
					mockMvc.perform(get("/employee/list"))
						.andExpect(handler().methodName("list"))
						.andExpect(status().isOk())
						.andExpect(view().name("home"))
						.andExpect(forwardedUrl("/WEB-INF/pages/home.jsp"))
						.andExpect(model().attribute("employeeList", allOf(
							not(nullValue()), hasSize(greaterThan(0))
						))).andDo(print());
				}
			
			}
		    
@WebAppConfiguration 用于声明为集成测试环境加载的 ApplicationContext 是一个 WebApplicationContext 类型。
@WebAppConfiguration 标注的 value 注解用于指定 web 应用的根路径, 默认是 @WebAppConfiguration("src/main/webapp")。
@WebAppConfiguration 注解需要 @ContextConfiguration 的支持。其余注解可参考本站点 junit 和 spring-test 相关文章。
MockMvc 有两种构建方式 :
1.MockMvcBuilders.webAppContextSetup(WebApplicationContext context), 从上下文环境中获取控制器以构建 MockMvc
2.MockMvcBuilders.standaloneSetup(Object... controllers), 通过指定的控制器来构建 MockMvc
测试流程大致为 :
MockMvc.perform, 执行一个请求
MockMvcRequestBuilders.get 构造一个请求
ResultActions.andExpect 结果断言
ResultActions.andDo 结果处理
执行测试, 结果如下 :
测试绑定参数到处理方法
		    @Test
			public void testSave() throws Exception {
				mockMvc.perform(get("/employee/save")
					.param("name", "店小四")
					.param("age", "20")
					.param("mail", "dianxiaosi@yeah.net"))
					.andExpect(handler().methodName("save"))
					.andExpect(status().isOk())
					.andExpect(view().name("home"))
					.andExpect(forwardedUrl("/WEB-INF/pages/home.jsp"))
					.andExpect(model().attribute("success", is(true)))
					.andDo(print());
			}
		    
通过 param(String, String...) 来传参到处理方法, 执行测试, 结果如下 :
测试绑定参数到URL模板
		    @Test
			public void testInfo() throws Exception {
				mockMvc.perform(get("/employee/info/{employeeId:[1-9]\\d*}", 2))
					.andExpect(handler().methodName("info"))
					.andExpect(status().isOk())
					.andExpect(forwardedUrl("/WEB-INF/pages/home.jsp"))
					.andExpect(model().attribute("employee",allOf(
						not(nullValue()), isA(Employee.class)
					))).andDo(print());
			}
		    
通过 get(String urlTemplate, Object... urlVariables) 绑定参数到URL模板, 执行测试, 结果如下 :
测试绑定JSON参数到处理方法
		    @Test
			public void testJsonSave() throws Exception {
				String employee = "{\"id\":null,\"age\":18,\"name\":\"店小六\",\"mail\":\"dianxiaoliu@163.com\"}";
				mockMvc.perform(post("/employee/json/save").contentType("application/json").content(employee))
					.andExpect(handler().methodName("save"))
					.andExpect(status().isOk())
					.andExpect(jsonPath("$").value(true))
					.andDo(print());
			}
		    
通过 content(String) 绑定JSONG参数到处理方法, jsonPath 用法参考 http://goessner.net/articles/JsonPath, 执行测试, 结果如下 :
测试返回JSON数据的处理方法
		    @Test
			public void testJsonInfo() throws Exception {
				mockMvc.perform(post("/employee/json/info/{employeeId:[1-9]\\d*}", "2").accept("application/json"))
					.andExpect(handler().methodName("info"))
					.andExpect(status().isOk())
					.andExpect(jsonPath("$.id").value(2))
					.andDo(print());
			}
		    
jsonPath 用法参考 http://goessner.net/articles/JsonPath, 执行测试, 结果如下 :

示例代码下载
SpringMVCTest.zip