DBUnit 支持Blob Clob

    在测试的时候,我们有时需要为数据库准备二进制数据,比如遇到ORACLE的 BLOB 类型的字段。BLOB可以存放任意的二进制数据,比如图片等。dbUnit从2.1版开始加入了对BLOB的支持(原文:“Ability to import external file for binary data types like BLOB; the value can be either a qualified URL or a file path name.”)但却没有给出任何文档说明何为“a qualified URL or a file path name”。而且看似要为每个二进制数据准备不同的文件,这也容易加大测试文件管理的复杂度,特别是有时候我们也许只需要输入几个byte的数据,这样我们就需要对dbUnit做一些进一步的开发来支持直接在种子文件中处理二进制数,其中主要利用ReplacementDataSet这个类。


    在详细说明如何支持二进制数之前先介绍以下如何支持空数据,假设种子文件中存在以下内容:

<?xml version='1.0' encoding='UTF-8'?> 
<DATASET> 
    <ACCOUNT id="1"
             username="Drew"
             password="[NULL]"
    />
    ……
</DATASET> 



    这条记录的密码允许为空,‘[NULL]’不是dbUnit的关键字,是我们自己定义的。在被提交给dbUnit之前,我们必须将它过滤掉,并用真正的null替代:

@Override 
protected IDataSet getDataSet() throws Exception  { 
	ReplacementDataSet dataSetnew FlatXmlDataSet((
	     new ReplacementDataSet(
                  new FileInputStream(“dataSetFilePath”))));
        dataFilter(dataSet);
        return dataSet;
} 
private void dataFilter(ReplacementDataSet dataSet) throws DataSetException { 
    // Filter NULL
    dataSet.addReplacementObject("[NULL]", null);
} 



    这样dataSet中的,被标记为”[NULL]”的值就都被null替换掉了。用这里我们用最简单的方式演示了ReplacementDataSet类的作用。类似的方法我们也可以让dbUnit替换我们需要转换成二进制的数据。现假设种子数据为以下形式:

<?xml version='1.0' encoding='UTF-8'?> 
<DATASET> 
    <ACCOUNT id="1"
             username="Drew"
             password="[NULL]"
             logonhours="[BINARY:e0ff01e0ff01e0ff01e0ff01e0ff01]"
    />
     ……
</DATASET> 



    和上例一样,这里的[BINARY:….]是我们自己定义的。我们只需要在提交给dbUnit之前找到并替换掉它就可以了,让我们扩充一下dataFilter方法,代码如下:

private void dataFilter(ReplacementDataSet dataSet) throws DataSetException { 
    static final String replacementPattern = "^\\[([^]]*)\\]$";
    static final String dataTypePattern = "^\\w+:*";
    static final String DATA_TYPE_NULL = "NULL";
    static final String DATA_TYPE_BINARY = "BINARY";
    static final String DATA_TYPE_FILE = "FILE";
    // Filter NULL
    dataSet.addReplacementObject("[" + DATA_TYPE_NULL +"]", null);
    ITableIterator tables = dataSet.iterator();
    // Fetch tables(1)
    while(tables.next()) {
        ITable table = tables.getTable();
        ITableMetaData metaData = table.getTableMetaData();
        Column[] columns = metaData.getColumns();
        // Fetch rows (2)
        int rowCount = table.getRowCount();
        for(int row=0; row<rowCount; row++){
            // Fetch columns (3)
            for(int i=0; i<columns.length; i++) {
            Column c = columns[i];
            String name = c.getColumnName();
            if(name.equals("logonhours")){
                logger.info("logonhours!!");
            }
            // Check value (4)
            String value = (String)table.getValue(row, name);
            if(null != value) {
                // Find "[TYPE:VALUE]"
                Pattern p=Pattern.compile(replacementPattern);
                Matcher m=p.matcher(value);
                if(m.find()) {
                    String matchedData = m.group(0);
                    String data= matchedData.substring(1,matchedData.length()-1);
                    p = Pattern.compile(dataTypePattern);
                    m = p.matcher(data);
                    if(m.find()) {
                        String type = m.group(0);
                        String v = data.substring(type.length());
                        type = type.substring(0,type.length()-1); 

                        // Filter Binary data (5)
                        if(type.toUpperCase().equals(DATA_TYPE_BINARY) {
                            byte[] bin = new byte[v.length()/2];
                            for(int index = 0; index<v.length()/2; index++) {
                                bin[index] =Integer.valueOf(v.substring(index*2,index*2+2),16).byteValue();
                            }
                            dataSet. addReplacementObject(matchedData,bin);
                        }
                         // Filter Binary data  end
                        if(type.toUpperCase().equals(DATA_TYPE_FILE)) {
                            logger.info( "Load data from file:"+v);
                        } else { 
                        logger.warn("Unsupport data type."); 
                        } 
                    } 
                 } 
             } 
          } 
       } 
    } 
} 

 

  1. 我们读取种子文件中的每一个表
  2. 然后读取每个表中的记录
  3. 再获得每条记录的字段
  4. 最后我们检查这些字段
  5. 并过滤出我们定义的关键字

      Filter Binary data 代码,们取出BINARY后面的字串并转换成byte[]类型,然后再放回去,这样就将文本输入转换成了二进制输入。


    这个方法还有些不完善的地方,首先,它只能简单的处理16进制输入,不能支持十进制,如果要支持十进制的话还需要进一步转换。其次,用类似的方法还可以处理文件输入,将输入定义成’[FILE:path_to_file]’的形式,然后在灰色代码部分实现对文件的读取并转换成二进制输入就可以。


    虽然dbUnit的设计初衷很好,但是不知为什么开发的很不完善,如果不做二次开发几乎是无法使用,但是只要经过合适的二次开发,它还是可以很好的满足需求。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值