spring3配置回滚测试

为什么需要回滚测试?

        在开发过程中进行单元测试的目的是为了让系统的更稳定。在实施测试驱动开发的时候发现一个问题,有些用例对数据有特定要求。因为测试过程本身会引起数据的变化,所以导致测试用例无法反复测试。

譬如添加一条主键id为10的记录:

测试用例可能是这样的 :
boolean handle= deptService.addDept(“10","测试部门10");
Assert.assertEquals(true,handle);
这个测试用例可以跑通,但是无法反复测试,因为第二次测试的时候就因为主键不能重复而报错。

解决方法:

        我们可以通过手动还原测试用例修改的内容。在刚刚的例子中可以在每次测试完成后删除那条记录。有的人已经发现这个好像也太麻烦了吧,数据简单还好,如果是一个比较复杂的操作对多张数据表进行修改,那些个测试用例也太累了吧。所以还有一个可选方案就是使用回滚测试,让测试用例执行完之后并不对数据库进行修改,这样也能实现用例反复测试的效果,而且无需添加手动代码。

spring3如何实现回滚测试?

前置条件      
1 spring3环境配置成功
2 可正常跑通junit测试
实现步骤:
1.继承spring事务测试类
继承AbstractTransactionalJUnit4SpringContextTests类(通常spring3的单元测试类AbstractJUnit4SpringContextTests)
2. 添加事务注解@TransactionConfiguration
2.1在测试类的上方进行注解  @TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false)   
2.2在需要回滚的方法上添加回滚标示  @Rollback(value=true)  
3.在applicationContext.xml配置文件中添加 dataSource配置
如果不适用回滚测试的话 dataSource是可以不进行配置的,但是这里必须进行配置。(这个dataSource配置的是挺奇怪的,因为在sessionFactory配置项中已经指定hibernate.cfg.xml替代数据源配置了,不过不写这个dataSource是会报错的)

代码参考:
1 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation"
			value="classpath:hibernate.cfg.xml">
		</property>
	</bean>	
	
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName">  
            <value>com.mysql.jdbc.Driver</value>  
        </property>  
        <property name="url">  
            <value>jdbc:mysql://localhost:3306/yusr?useUnicode=true&characterEncoding=UTF-8</value>  
        </property>  
        <property name="username">  
            <value>root</value>  
        </property>  
        <property name="password">  
            <value>root</value>  
        </property>  
    </bean> 
    
    
   
    
	<!-- 配置事务管理 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref bean="sessionFactory"/>
		</property>
	</bean>
	<!-- 配置事务的传播性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED"/>
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="remove*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="get*" propagation="REQUIRED"/>	
			<tx:method name="find*" propagation="REQUIRED"/>	
			<tx:method name="turn*" propagation="REQUIRED"/>
			<tx:method name="del*" propagation="REQUIRED"/>
			<tx:method name="move*" propagation="REQUIRED"/>
			<tx:method name="edit*" propagation="REQUIRED"/>
			<tx:method name="test*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	<!-- 配置事务管理的哪些方法 --> 
	<aop:config>
		<aop:pointcut id="allServiceMethod" expression="execution(* com.metecyu.*.dao.*.*(..)) or execution(* com.metecyu.*.service.*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethod"/>
	</aop:config>
	<!-- yzp:true:表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理(不过这个项目不加就会报错,其它项目都不需要,我想可能是包版本的关系)--> 
	<aop:aspectj-autoproxy proxy-target-class="true" />
	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
	
	<context:component-scan base-package="com.metecyu.yusr.dao" />
	<context:component-scan base-package="com.metecyu.yusr.service" />
	
	
	<!-- 
	<context:component-scan base-package="com.megait.cw.task.service" />
	<context:component-scan base-package="com.megait.xmgl.comm.service" /> -->
</beans>

2 测试用例
package com.metecyu.yusr.dao;
import java.util.List;

import javax.annotation.Resource;

import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import com.metecyu.yusr.model.Dept;
import com.metecyu.yusr.service.DeptService;

@TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false)  
@ContextConfiguration(locations={"/applicationContext.xml","/hibernate.cfg.xml"})
public class DeptDAOTest  extends AbstractTransactionalJUnit4SpringContextTests  {
	private static final Logger log = Logger.getLogger(DeptDAOTest.class);
	
	@Resource
	private DeptDAO deptDAO; 
	@Resource
	DeptService deptService;
	
	@Test
	@Rollback(value=true)  
	public void testGetNewId(){
		String deptid = "testDept";
		String newDeptid = deptDAO.getNewDeptid(deptid);
		Assert.assertEquals("和原id相同",newDeptid, deptid); 
		
		deptService.addDept(deptid,"测试部门","测试部门","1");
		newDeptid = deptDAO.getNewDeptid(deptid);
		Assert.assertEquals("第一次id重复,编号为01",newDeptid, deptid+"@01"); 
		
		
		deptService.addDept(deptid+"@01","测试部门@01","","1");
		deptService.addDept(deptid+"@02","测试部门@02","","1");
		deptService.addDept(deptid+"@03","测试部门@03","","1");
		newDeptid = deptDAO.getNewDeptid(deptid);
		Assert.assertEquals("多条id重复,编号为当前末尾编号加1",newDeptid, deptid+"@04");
		
		deptService.addDept(deptid+"@20","测试部门@20","","1");
		newDeptid = deptDAO.getNewDeptid(deptid);
		Assert.assertEquals("多条id重复,编号为当前末尾编号加1",newDeptid, deptid+"@21"); 
		
		
		deptService.addDept(deptid+"@99","测试部门@99","","1");
		newDeptid = deptDAO.getNewDeptid(deptid);
		Assert.assertNotSame("第一次id重复,编号为01",newDeptid, deptid+"@00"); 
		
		
	}
	
	
	@Test
	@Rollback(value=true)  
	public void testGenarateDeptId() throws BadHanyuPinyinOutputFormatCombination{
		String deptname = "测试部门";
		String newDeptid = deptDAO.genarateDeptId(deptname);
		Assert.assertEquals("和原id相同",newDeptid, "csbm"); 
		
		deptService.addDept("csbm","测试部门","测试部门","1");
		newDeptid = deptDAO.genarateDeptId(deptname);
		Assert.assertEquals("第一次id重复,编号为01",newDeptid, "csbm@01"); 
		
		
	}	

}










  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值