今天在对基于Spring mvc架构的项目写单元测试的时候,本来想用@RunWith的方式轻松搞定它。不曾想还不是那么so easy,
一方面是controller层没有联系起来,再者就是SpringJUnit4ClassRunner启动就报不知道什么鬼错了。索性就换成mock方式,再熟悉一下spring容器加载机制也未尝不是一件好事~ 废话少说,直接上代码先!!!
测试基类
package com.andy.test;
import java.io.File;
import java.util.Arrays;
import java.util.Map;
import javacommon.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping;
/**
*
* Spring MVC 3.0 Controller层测试基类
* 提供Controller层测试stub
*
* @author Andy
* @since 2012.5.10 1:25 PM
* @version 1.0
*
*/
public abstract class AbstractTestCase {
// 应用程序根配置文件(不包含applicationContext.xml配置文件)
private final static String[] ROOT_CONFIGLOCATION = {"classpath:/spring/*-test.xml"};
// 随Servlet启动时加载配置文件。(默认为applicationContext.xml/servletName-servlet.xml)
private final static String DEFAULT_CONFIG_LOCATION = "classpath:/spring/applicationContext.xml";
// 模块功能CRUD
protected final static String MODULE_QUERY = "query";
protected final static String MODULE_LIST = "list";
protected final static String MODULE_SHOW = "show";
protected final static String MODULE_CREATE = "create";
protected final static String MODULE_SAVE = "save";
protected final static String MODULE_EDIT = "edit";
protected final static String MODULE_DELETE = "delete";
// Logger
protected final static Logger logger;
// 对象映射处理器(映射到controller类)
protected HandlerMapping handlerMapping;
// 方法适配处理器(映射到具体方法)
protected HandlerAdapter handlerAdapter;
// Spring容器上下文
protected XmlWebApplicationContext webApplicationContext;
static{
// 清除旧的测试日志文件
File logFile = null;
logFile = new File("logs/test.log");
if(logFile.exists()){
logFile.setReadable(true);
logFile.setWritable(true);
logFile.delete();
}
// 加载测试日志配置文件
PropertyConfigurator.configure(AbstractTestCase.class.getResource("/log4j-test.properties"));
logger = Logger.getLogger(AbstractTestCase.class);
}
@Before
public void setUp(){
// 创建web应用程序根上下文,该上下文解析并管理系统实例
XmlWebApplicationContext rootWebApplicationContext = new XmlWebApplicationContext();
rootWebApplicationContext.setConfigLocations(ROOT_CONFIGLOCATION);
// 创建servletContext上下文
MockServletContext servletContext = new MockServletContext();
rootWebApplicationContext.setServletContext(servletContext);
rootWebApplicationContext.refresh();
//servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootWebApplicationContext);
// 创建web应用程序上下文,管理controller层请求业务
webApplicationContext = new XmlWebApplicationContext();
webApplicationContext.setConfigLocation(DEFAULT_CONFIG_LOCATION);
webApplicationContext.setParent(rootWebApplicationContext);
webApplicationContext.refresh();
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext);
// 获取默认mapping,adapter
handlerMapping = webApplicationContext.getBean(ControllerClassNameHandlerMapping.class);
handlerAdapter = webApplicationContext.getBean(AnnotationMethodHandlerAdapter.class);
}
// TODO 测试流程 创建->修改->查询-> 删除
@Test
public void testMain(){
// 创建
this.testCreateUI();
this.testSave();
// 修改
this.testEditUI();
this.testUpdate();
// 查询
this.testQuery();
this.testList();
this.testShow();
// 删除
this.testDelete();
}
/**
* 跳转到创建UI
*/
protected abstract void testCreateUI();
/**
* 创建功能
*/
protected abstract void testSave();
/**
* 跳转到编辑UI
*/
protected abstract void testEditUI();
/**
* 修改功能
*/
protected abstract void testUpdate();
/**
* 按条件查询
*/
protected abstract void testQuery();
/**
* 分页查询所有记录
*/
protected abstract void testList();
/**
* 查询某条记录详情
*/
protected abstract void testShow();
/**
* 删除某条记录
*/
protected abstract void testDelete();
/**
* 执行请求
* @param request http请求对象
* @param response http响应对象
* @return UI信息
*/
protected ModelAndView execute(HttpServletRequest request , HttpServletResponse response){
try {
HandlerExecutionChain chain = handlerMapping.getHandler(request);
return handlerAdapter.handle(request, response, chain.getHandler());
} catch (Exception e) {
// TODO 忽略 no thread bind request exception。
// 如报错,在业务方法引入HttpServletRequest即可。(eg. public void save(HttpServletRequest request){ // statement})
}
return null;
}
/**
* 封装请求信息
* @param uri 请求uri
* @param method 请求类型 默认请求类型为GET
* eg POST GET PUT DELETE HEAD TRACE OPTIONS
* @param params 请求参数
* @return http请求对象
*/
protected HttpServletRequest createRequest(String uri , Map<String , String> params , RequestMethod... method ){
if(null == uri || uri.isEmpty()){
throw new IllegalArgumentException("It must contains request uri!");
}
// 构造请求
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI(uri);
if(null == method || method.length == 0){
request.setMethod(RequestMethod.GET.name());
}else{
request.setMethod(method[0].name());
}
if(null != params && !params.isEmpty()){
request.addParameters(params);
}
return request;
}
@After
public void tearDown(){
}
// 查询相关
/**
* 查询所有数据记录
*
* @param module 当前模块
* @param operate 当前操作
*/
protected void list(String module, String operate){
ModelAndView view = this.processRequest(module + operate, null);
logger.info(StringUtils.format("【Unit Testing Info】query {0}: {1}.", module , view));
}
/**
* 查询某个记录详情
* @param module 当前模块
* @param operate 当前操作
* @param params 某记录数据参数
* @param method 请求类型
*/
protected void show(String module, String operate , Map<String,String> params , RequestMethod method){
Assert.notEmpty(params, "The request params is null!");
ModelAndView view = this.processRequest(module + operate, params, method);
logger.info(StringUtils.format("【Unit Testing Info】 query {0} by params {1}: {2}.", module , params, view));
}
/**
* 多条件查询数据
* @param module 当前模块
* @param operate 当前操作
* @param params 条件数据参数
* @param method 请求类型
*/
protected void query(String module, String operate , Map<String,String> params , RequestMethod method){
ModelAndView view = this.processRequest(module + operate, params, method);
logger.info(StringUtils.format("【Unit Testing Info】 query {0} by params {1}: {2}.", module , params, view));
}
// 创建修改相关
/**
* 请求待创建页面
*
* @param module 当前模块
* @param operate 当前操作
*/
protected void create(String module, String operate){
ModelAndView view = this.processRequest(module + operate, null);
logger.info(StringUtils.format("【Unit Testing Info】 {0} create url: {1}.", module , view));
}
/**
* 请求待修改页面
* @param module 当前模块
* @param operate 当前操作
* @param params 待数据参数
*/
protected void edit(String module, String operate , Map<String,String> params){
Assert.notEmpty(params, "The request params is null!");
ModelAndView view = this.processRequest(module + operate, params);
logger.info(StringUtils.format("【Unit Testing Info】 {0} edit url: {1}.", module , view));
}
/**
* 创建/修改数据请求
* @param module 当前模块
* @param operate 当前操作
* @param params 创建/修改数据参数
* @param method 请求类型
*/
protected void saveOrModify(String module, String operate , Map<String,String> params , RequestMethod method){
Assert.notEmpty(params, "The request params is null!");
this.processRequest(module + operate, params , method);
logger.info(StringUtils.format("【Unit Testing Info】 {0} save {1} success.", module , params));
}
// 删除操作
/**
* 删除数据请求
* @param module 当前模块
* @param operate 当前操作
* @param params 删除数据参数
*/
protected void delete(String module, String operate , Map<String,String[]> params){
Assert.notEmpty(params, "The request params is null!");
this.processRequest(module + operate, params);
logger.info(StringUtils.format("【Unit Testing Info】 {0} delete {1} success", module , Arrays.asList(params.get("ids"))));
}
/**
* 处理用户请求
*
* 实现构造请求数据,并发送请求,处理请求业务
*
* @param uri 请求uri
* @param method 请求类型 默认请求类型为GET
* eg POST GET PUT DELETE HEAD TRACE OPTIONS
* @param params 请求参数
* @return 请求结果
*/
@SuppressWarnings({"rawtypes" , "unchecked"})
protected ModelAndView processRequest(String uri , Map params , RequestMethod... method ){
HttpServletRequest request = this.createRequest(uri, params);
HttpServletResponse response = new MockHttpServletResponse();
return this.execute(request, response);
}
}
单元测试用例类
package com.andy.test.unit;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMethod;
import com.andy.dao.UserDao;
import com.andy.dao.RoleDao;
import com.andy.dao.RightsDao;
import com.andy.model.User;
import com.andy.model.Role;
import com.andy.model.Rights;
import com.andy.test.AbstractTestCase;
/**
* 用户管理模块测试用例
*
* @author Andy
* @since 2012.5.10 04:45 PM
* @version 1.0
*/
@SuppressWarnings("unchecked")
public class UserManagerTestCase extends AbstractTestCase{
// 用户管理包含子模块
private final static String USER_MODULE = "/user/";
private final static String ROLR_MODULE = "/role/";
private final static String RIGHTS_MODULE = "/rights/";
// 测试id
private Long userTestId;
private Long roleTestId;
private Long rightsTestId;
@Override
protected void testCreateUI() {
// TODO Auto-generated method stub
}
@Override
protected void testSave() {
// TODO Auto-generated method stub
}
@Override
protected void testEditUI() {
// TODO Auto-generated method stub
}
@Override
protected void testUpdate() {
// TODO Auto-generated method stub
}
@Override
protected void testQuery() {
// TODO Auto-generated method stub
}
@Override
protected void testList() {
// TODO Auto-generated method stub
}
@Override
protected void testShow() {
// TODO Auto-generated method stub
}
@Override
protected void testDelete() {
// TODO Auto-generated method stub
}
}
分享到:
相关推荐
spring3.0 全部jar包 spring3.0 全部jar包 spring3.0 全部jar包
不仅讲解了Spring3.0的基础知识,还深入讨论了SpringIoC容器、SpringAOP、使用SpringJDBC访问数据库、集成Hibernate、Spring的事务管理、SpringMVC、单元测试、敏捷开发技术等内容,帮助读者快速入门并可以立刻使用...
《Spring3.0就这么简单》适合于具有一定Java编程基础的读者,以及在Java平台下进行各类软件开发的开发人员和测试人员等。 Spring 3.0就这么简单_Part1.pdf Spring 3.0就这么简单_Part2.pdf Spring 3.0就这么简单_...
spring3.0 开发包,开发J2ee,值得拥有
Spring 3.0重要特性总结如下: ◆Spring表达式(SpEL):用于bean定义的核心表达式分析器 ◆对基于注释的组件的更多支持:允许通过元注释创建注释的“快捷方式” ◆标准化的依赖性注入注释:对Java中依赖性注入的...
spring3.0的API,spring3.0的API
spring3.0 jar包
spring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 api
spring3.0 项目源码 spring3.0 注解 的学习,spring mvc 完整项目, 请你好好学习一下!
spring 3.0 jar包,下载无需资源分,希望大家能够用得到,另外强烈鄙视那些上传资源不完整,不经过测试的人。
Struts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdf
Spring3.0学习文档主要讲解的是IOC和AOP 静态代理、动态代理这些内容是Spring3.0中最难理解的重点知识点
spring3.0Mvc简单示例 导入即可运行
spring3.0+spring mvc3.0+mybaits3.0
spring 3.0 必须的 jar 包。
spring 3.0 source code project
介绍一个基于Spring Boot 3.0、Spring Cloud 2022 & Alibaba的微服务RBAC权限管理系统。该系统可以实现微服务RBAC权限管理,通过RBAC权限管理机制对用户访问系统的权限进行限制,从而提高系统的安全性和可用性。同时...
Spring3.0+myBatis3.0