`
niuzai
  • 浏览: 67924 次
  • 性别: 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包

    Spring 3.0 是一个重要的Java应用程序框架,主要用于构建企业级的、基于组件的、松散耦合的应用程序。这个框架以其灵活性、可..."spring3.0 全部jar包"则为开发者提供了构建基于Spring 3.0应用程序所需的所有基础工具。

    spring3.0完整框架

    4. **注解驱动开发**:Spring 3.0大大扩展了注解的应用,例如@Controller、@Service、@Repository和@Service,它们分别用于标记控制器、服务层、数据访问层的类,简化了依赖注入。 5. **AOP增强**:Spring 3.0增强...

    spring 3.0 jar包

    Spring 3.0大力推广了注解驱动的开发方式,如@Controller、@Service、@Repository和@Service等,减少了XML配置的使用,提升了开发效率。这些注解使组件的定义更加直观,降低了配置复杂性。 3. **AOP增强**: 在...

    spring 3.0 jar 包

    11. **Test支持**:Spring 3.0提供了Spring TestContext Framework,用于单元测试和集成测试,支持JUnit和TestNG。 在使用"spring 3.0.0"这个压缩包时,开发者需要确保包含所有必要的jar文件,例如`spring-beans....

    Spring3.0Jar包

    11. **Spring Test**:Spring 3.0 强化了测试支持,提供了 `@ContextConfiguration` 和 `@Test` 等注解,使得单元测试和集成测试更为便捷。 12. **Web Flow**:Spring Web Flow 是 Spring 3.0 中的一个子项目,用于...

    spring3.0发行版

    此外,Spring 3.0的MVC框架支持模板引擎,如FreeMarker和Velocity,简化了视图层的开发。 在数据访问和事务管理领域,Spring 3.0加强了JPA和Hibernate的支持,提供了更好的ORM集成。同时,它改进了对JDBC的支持,...

    spring3.0轻量级框架

    在Spring 3.0中,对依赖注入(Dependency Injection, DI)进行了优化,支持了基于注解的配置,开发者可以使用@Component、@Service、@Repository和@Controller等注解来声明bean,并通过@Autowired自动装配依赖。...

    spring3.0jar包集合

    Spring 3.0提供了一套全面的测试工具,包括`@RunWith(SpringJUnit4ClassRunner.class)`用于Spring测试,以及模拟对象和数据源的工具,方便单元测试和集成测试。 这些只是Spring 3.0框架中的一部分关键特性,其丰富...

    spring3.0MVC 含jar包

    Spring 3.0提供模拟HTTP请求的MockMvc工具,方便进行单元测试和集成测试。测试控制器的逻辑变得更加简单,提高了代码质量。 总结: Spring 3.0 MVC以其优秀的架构设计、丰富的功能和高度的灵活性,成为Java Web开发...

    Spring 3.0就这么简单源码Maven的jar包001

    首先,Spring 3.0的一大亮点是增强了对Java 5和6的支持,引入了基于注解的配置,大大减少了XML配置文件的数量和复杂性。开发者可以使用如`@Autowired`、`@Service`、`@Repository`和`@Controller`等注解,直接在类或...

    spring3.0jar包

    8. **Spring Test**:测试模块提供了对Spring应用进行单元测试和集成测试的支持,包括ApplicationContext的加载和模拟对象的使用,便于进行测试驱动开发(TDD)。 9. **Spring Expression Language (SpEL)**:...

    Spring 3.0就这么简单.pdf

    2. **AOP(Aspect Oriented Programming, 面向切面编程)**:Spring 3.0对AOP进行了优化,支持更多样化的切面定义,包括基于注解的切面,使得事务管理、日志记录等横切关注点的处理更加简洁。 3. **MVC(Model-View...

    spring3.0 mvc和rest入门例子

    在压缩包文件"spring3_rest"中,可能包含了一个简单的Spring 3.0 MVC和REST的例子,你可以通过这个例子学习如何配置Spring MVC的DispatcherServlet,创建RESTful端点,处理请求和响应,以及如何使用JUnit进行测试。...

    Spring3.0源码3

    在这个“Spring3.0源码3”中,我们将深入探讨Spring 3.0的核心组件和设计理念,以及它在实际开发中的应用。 1. **依赖注入(DI, Dependency Injection)**:Spring的核心特性之一,允许对象之间的依赖关系通过配置...

    Java框架spring3.0

    9. **测试框架改进**:Spring Test模块加强了对JUnit和TestNG的支持,提供了更丰富的测试工具和上下文管理,便于进行单元测试和集成测试。 10. **Web Flow集成**:Spring Web Flow与Spring MVC的集成进一步完善,为...

    spring3.0帮助文档

    以上只是Spring 3.0配置知识的一部分,实际文档中会涵盖更多细节,包括如何配置数据源、事务管理、缓存、任务调度等,以及如何使用Spring的测试框架进行单元测试和集成测试。通过深入学习和理解这些配置机制,开发者...

    Spring 3.0就这么简单源码Maven的jar包002

    注解驱动的开发是Spring 3.0的一大亮点,它允许开发者通过在类和方法上使用注解来简化配置,如@Service、@Repository和@Controller,这些注解分别用于标记服务、数据访问对象和控制器组件。此外,@Autowired自动装配...

    Spring3.0官方英文文档

    Spring 3.0提供了全面的测试支持,包括单元测试和集成测试。Spring TestContext Framework提供了诸如@ContextConfiguration、@RunWith等注解,方便测试环境的配置和管理。 总的来说,Spring 3.0的官方文档详尽地...

    spring 3.0帮助文档

    2. **注解驱动开发(Annotation-based Development)**:Spring 3.0引入了大量的注解,如@Service、@Controller、@Repository和@Transactional,减少了XML配置,提高了代码可读性。例如,@Autowired用于自动装配依赖,...

Global site tag (gtag.js) - Google Analytics