一個通用的單元測試框架的思考和設計01-思考篇
一個通用的單元測試框架的思考和設計02-設計篇
一個通用的單元測試框架的思考和設計03-實現篇-核心類源碼
一個通用的單元測試框架的思考和設計04-實現篇-自動管理測試數據
一個通用的單元測試框架的思考和設計05-實現篇-Guice框架啓動與自動注入
一個通用的單元測試框架的思考和設計06-實現篇-自動管理測試數據-如何臨時關閉數據外鍵約束
一個通用的單元測試框架的思考和設計07-實現篇-自動管理測試數據-如何爲自增長主鍵id賦值
有時候,僅僅依靠框架提供的xml方式來插入和刪除數據時不夠的,有的時候需要在測試代碼中執行一些sql語句,以下是介紹如何便捷的做到這一點
前幾章節我們介紹過了,我們是靠dbuint來進行測試數據的維護的,而dbunit給我們提供了一個非常好的接口IDatabaseTester,這個接口中定義了一些與數據庫連接相關的操作,在我們的框架中也是用這種方式來維護數據庫連接的。
1.定義一個接口
public interface IDatabaseTesterAware {
/**
* 設置Tester對象
* @param databaseTester
* @see org.dbunit.IDatabaseTester
*/
public void setIDatabaseTester(IDatabaseTester databaseTester);
}
2.在我們的testCase類中實現該接口-一般在basetestcase中實現,具體的測試類直接可以使用了
@TestExecutionListeners({ XmlDatasetProviderListener.class, TransactionalTestExecutionListener.class })
public class BaseHopTestCase extends AbstractJUnit4SpringContextTests implements IDatabaseTesterAware{
protected IDatabaseTester databaseTester;
@Override
public void setIDatabaseTester(IDatabaseTester databaseTester) {
this.databaseTester = databaseTester;
}
}
3.在框架中將IDatabaseTester注入
找到我們框架裏的DatasetProviderListener 的prepareTestInstance方法,在該方法的最後
//將測試IDatabaseTester注入到測試類中
if(testInstance instanceof IDatabaseTesterAware){//在這裏爲testcase中的IDatabaseTester賦值
IDatabaseTesterAware databaseTesterAware = (IDatabaseTesterAware)testInstance;
databaseTesterAware.setIDatabaseTester(databaseTester);
}
這樣我們的基類testcase中就可以定義常用到的方法了,如下
@TestExecutionListeners({ XmlDatasetProviderListener.class, TransactionalTestExecutionListener.class })
public class BaseTestCase extends AbstractJUnit4SpringContextTests implements IDatabaseTesterAware{
protected IDatabaseTester databaseTester;
@Override
public void setIDatabaseTester(IDatabaseTester databaseTester) {
this.databaseTester = databaseTester;
}
/**
* 利用dbunit的connection執行sql語句
* @param sql
*/
protected void executeSQL(String sql){
Connection connection = null;
Statement statement = null;
try {
connection = databaseTester.getConnection().getConnection();
statement = connection.createStatement();
statement.execute(sql);
}catch (Exception e) {
ReflectionUtils.handleReflectionException(e);
}finally{
closeStatement(statement);
closeConnection(connection);
}
}
/**
* 關閉數據庫連接
* @param connection
*/
protected void closeConnection(Connection connection) {
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
ReflectionUtils.handleReflectionException(e);
}
}
}
/**
* 關閉sql語句對象
* @param statement
*/
protected void closeStatement(Statement statement){
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
ReflectionUtils.handleReflectionException(e);
}
}
}
/**
* 生成默認的刷新物化視圖的sql語句--僅限於oracle
* @param materializedViewName 物化視圖的名字
* @return
*/
protected String generateRefeshMaterializedViewSql(String materializedViewName){
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("BEGIN")
.append(" DBMS_SNAPSHOT.REFRESH")
.append(" (LIST => '")
.append(materializedViewName).append("'")
.append(" ,PUSH_DEFERRED_RPC => TRUE")
.append(" ,REFRESH_AFTER_ERRORS => FALSE")
.append(" ,PURGE_OPTION => 1")
.append(" ,PARALLELISM => 0")
.append(" ,ATOMIC_REFRESH => TRUE")
.append(" ,NESTED => FALSE);")
.append(" END;");
return stringBuffer.toString();
}
/**
* 刷新指定的物化視圖
* @param materializedViewName 物化視圖名字
*/
protected void refeshMaterializedView(String materializedViewName){
executeSQL(generateRefeshMaterializedViewSql(materializedViewName));
}
}
其中有一個重要的功能就是刷新物化視圖的功能