`
niuzai
  • 浏览: 67418 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

基于Spring 3.0 Controller层单元测试

 
阅读更多

   今天在对基于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

	}
}
 

 

 

3
0
分享到:
评论
1 楼 ljlowkey 2015-11-09  
楼主import javacommon.util.StringUtils; 这个是什么jar包

相关推荐

    spring3.0 全部jar包

    spring3.0 全部jar包 spring3.0 全部jar包 spring3.0 全部jar包

    Spring 3.0就这么简单源代码

    不仅讲解了Spring3.0的基础知识,还深入讨论了SpringIoC容器、SpringAOP、使用SpringJDBC访问数据库、集成Hibernate、Spring的事务管理、SpringMVC、单元测试、敏捷开发技术等内容,帮助读者快速入门并可以立刻使用...

    Spring 3.0就这么简单_Part3.pdf

    《Spring3.0就这么简单》适合于具有一定Java编程基础的读者,以及在Java平台下进行各类软件开发的开发人员和测试人员等。 Spring 3.0就这么简单_Part1.pdf Spring 3.0就这么简单_Part2.pdf Spring 3.0就这么简单_...

    spring3.0jar包

    spring3.0 开发包,开发J2ee,值得拥有

    spring3.0帮助文档(包含REST资料)

    Spring 3.0重要特性总结如下: ◆Spring表达式(SpEL):用于bean定义的核心表达式分析器 ◆对基于注释的组件的更多支持:允许通过元注释创建注释的“快捷方式” ◆标准化的依赖性注入注释:对Java中依赖性注入的...

    spring3.0的API

    spring3.0的API,spring3.0的API

    spring3.0 jar包

    spring3.0 jar包

    spring3.0 api

    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 项目源码 spring3.0 注解 的学习,spring mvc 完整项目, 请你好好学习一下!

    spring 3.0 jar包

    spring 3.0 jar包,下载无需资源分,希望大家能够用得到,另外强烈鄙视那些上传资源不完整,不经过测试的人。

    Struts2.1+Spring3.0+JPA1.0 .pdf

    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学习文档

    Spring3.0学习文档主要讲解的是IOC和AOP 静态代理、动态代理这些内容是Spring3.0中最难理解的重点知识点

    spring3.0Mvc简单示例

    spring3.0Mvc简单示例 导入即可运行

    spring3.0+spring mvc3.0+mybaits3.0

    spring3.0+spring mvc3.0+mybaits3.0

    spring 3.0 jar 包

    spring 3.0 必须的 jar 包。

    spring 3.0 source code

    spring 3.0 source code project

    基于Spring Boot 3.0、 Spring Cloud 2022 & Alibaba 的微服务RBAC 权限管理系统

    介绍一个基于Spring Boot 3.0、Spring Cloud 2022 & Alibaba的微服务RBAC权限管理系统。该系统可以实现微服务RBAC权限管理,通过RBAC权限管理机制对用户访问系统的权限进行限制,从而提高系统的安全性和可用性。同时...

    Spring3.0+myBatis3.0

    Spring3.0+myBatis3.0

Global site tag (gtag.js) - Google Analytics