有时候,仅仅依靠框架提供的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)); } }其中有一个重要的功能就是刷新物化视图的功能