一、Spring提供的JUnit框架扩展:
1.AbstractSpringContextTests:spring中使用spring上下文测试的Junit扩展类,我们一般不会使用这个类来进行单元测试,它是spring内部设计使用到的类
2.AbstractDependencyInjectionSpringContextTests:这是AbstractSpringContextTests的直接子类,支持依赖spring上下文的测试类,这个类不支持事务。
3.AbstractTransactionalSpringContextTests: 这是 AbstractDependencyInjectionSpringContextTests的直接子类,这个类一般应用在事务相关的测试中,一旦完成 每个测试它就会正常地回滚事务,不会真正更新数据库,若要手动设置事务相关操作,你可以重载onSetUpInTransaction和 onTearDownInTransaction方法,以便手工开始并提交事务,或者调用setComplete()方法。这个类也可以在没有事务的情况 下,使用这个类。
4.AbstractTransactionalDataSourceSpringContextTests:这是 AbstractTransactionalSpringContextTests的直接子类,它使用了Spring的基于JDBC的 jdbcTemplate工具类,支持数据库级别的事务。
package com.hsaction.framework.core.test.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* <p>Title:基于事务处理的测试类</p>
* <p>Description:为测试提供了一个自动回滚的测试机制。当基于本类测试时,每个测试用例的操作在测试完毕后均被回滚。</p>
* <p>Copyright: Copyright (c) 2007 邢修义 (Hubert Star)</p>
* <p>Company: HS Action Computer Tech. Studio</p>
* @author 邢修义
* <p>Datetime 2007-3-24 上午01:38:41</p>
*/
/* -------------------------修订记录--------------------------------
* 1.
* 修改原因:
* 修改内容:
* 修改时间:
* 修改人员:
* ---------------------------------------------------------------
*/
public abstract class AbstractTransactionalSpringContextNGTestCase extends AbstractNGTestCase {
/**
* Logger for this class
*/
private static final Log logger = LogFactory.getLog(AbstractTransactionalSpringContextNGTestCase.class);
protected PlatformTransactionManager transactionManager;
private boolean defaultRollback = true;
private boolean complete = false;
private int transactionsStarted = 0;
protected TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
protected TransactionStatus transactionStatus;
/**
* 默认的构造方法
*/
public AbstractTransactionalSpringContextNGTestCase() {
super();
}
/**
* 事务之前的处理,子类必须实现此方法
* @throws Exception
*/
protected abstract void onSetUpBeforeTransaction() throws Exception;
/**
* 事务清理之后的处理,子类必须实现此方法
* @throws Exception
*/
protected abstract void onTearDownAfterTransaction() throws Exception;
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void setDefaultRollback(boolean defaultRollback) {
this.defaultRollback = defaultRollback;
}
protected void preventTransaction() {
this.transactionDefinition = null;
}
protected void setTransactionDefinition(TransactionDefinition customDefinition) {
this.transactionDefinition = customDefinition;
}
/**
* 开始事务过程之中的处理方法,可以选择实现
* @throws Exception
*/
protected void onSetUpInTransaction() throws Exception {
}
/**
* 结束事务过程之中的处理方法,可以选择实现
* @throws Exception
*/
protected void onTearDownInTransaction() throws Exception {
}
/**
* 实现基类中的方法前准备工作,此处开始一个新事务
* @throws Exception
*/
protected final void onSetup() throws Exception {
this.complete = !this.defaultRollback;
if (this.transactionManager == null) {
logger.info("No transaction manager set: test will NOT run within a transaction");
} else if (this.transactionDefinition == null) {
logger.info("No transaction definition set: test will NOT run within a transaction");
} else {
this.onSetUpBeforeTransaction();
this.startNewTransaction();
try {
this.onSetUpInTransaction();
} catch (Exception ex) {
this.endTransaction();
throw ex;
}
}
}
/**
* 实现基类中的方法执行后清理工作,此处结束事务
* @throws Exception
*/
protected final void onTearDown() throws Exception {
if (this.transactionStatus != null && !this.transactionStatus.isCompleted()) {
try {
this.onTearDownInTransaction();
} finally {
this.endTransaction();
}
}
if (this.transactionsStarted > 0) {
this.onTearDownAfterTransaction();
}
}
/**
* 设置执行行为为测试后提交事务,默认事务是测试完毕马上回滚的
*
*/
protected void setComplete() {
if (this.transactionManager == null) {
throw new IllegalStateException("No transaction manager set");
}
this.complete = true;
}
/**
* 开始事务
* @throws TransactionException
*/
protected void startNewTransaction() throws TransactionException {
if (this.transactionStatus != null) {
throw new IllegalStateException("Cannot start new transaction without ending existing transaction: " + "Invoke endTransaction() before startNewTransaction()");
}
if (this.transactionManager == null) {
throw new IllegalStateException("No transaction manager set");
}
this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition);
++this.transactionsStarted;
this.complete = !this.defaultRollback;
if (logger.isInfoEnabled()) {
logger.info("Began transaction (" + this.transactionsStarted + "): transaction manager [" + this.transactionManager + "]; default rollback = " + this.defaultRollback);
}
}
/**
* 结束事务,根据complete决定提交或者回滚事务
*
*/
protected void endTransaction() {
if (this.transactionStatus != null) {
try {
if (!this.complete) {
this.transactionManager.rollback(this.transactionStatus);
logger.info("Rolled back transaction after test execution");
} else {
this.transactionManager.commit(this.transactionStatus);
logger.info("Committed transaction after test execution");
}
} finally {
this.transactionStatus = null;
}
}
}
}