顯示具有 unittest 標籤的文章。 顯示所有文章
顯示具有 unittest 標籤的文章。 顯示所有文章

2013年7月19日 星期五

hsqldb - 如何擴展沒有的FUNCTION以適應其他sql ?

參考:src_jrt_routines

寫Test的時候遇到一個問題,我想在我的SQL Query中使用 LEN()這個mssql function:

 
  SELECT LEN(str) FROM TABLE where name='123'

然而由於寫Test時使用的並非mssql而是使用hsqldb,hsqldb並不支援LEN(),
而是使用LENGTH(),如果將我的SQL Query改為 LENGTH(),在正式上線時又會遇到
MS-SQL並沒有LENGTH()的問題....因此該怎麼做比較好呢??

原來hsqldb有擴展function的機制,就是為了預防這個問題的產生:

  1. create一個擴展的java class如下(注意function一定得為static,詳細使用對應的參數型別請參考上述參考頁):
  2.  
    package util.extend.mssql;
    
    public class MSSql {
     public static int len(String str) {
      return str.length();
     }
    }
    
  3. 並於實際執行有用到LEN的SQL Query的地方之前,使用下列SQL Query
     
          CREATE FUNCTION  len(str VARCHAR(20000))
            RETURNS INT 
     LANGUAGE JAVA DETERMINISTIC NO SQL
     EXTERNAL NAME 'CLASSPATH:util.extend.mssql.MSSql.len'
    

  4. 以上若完成,執行test,應該就能成功囉
這機制真是太方便了!!!

p.s話說回來完全找不到相關的中文討論阿....是說寫Test的人真的很少還是高手都直接找英文了呢....0rz...網路上查到的方式Create alias也是過時的方式,害我花了不少時間找...

2013年7月6日 星期六

dbunit初體驗 - 從現有XML DATA中過濾出需要的資料

之前使用的QueryDataSet可以下SQL Query來SELECT出想要的資料(請見此篇),
然而QueryDataSet好像只能接受從connection資料來建立...這不符合我的需求,找到一個好方法,就是使用RowFilterTable 搭配IRowFilter,直接來看code:


 public static ITable filterXmlDataCol(
   String xmlDataFile, String tableName,IDatabaseConnection conn
   , final String expectColNames[] , final Object expectColVals[]) throws Exception {
  
  IDataSet databaseDataSet = getDataSetFromXmlFile(xmlDataFile);
  ITable actualTable = databaseDataSet.getTable(tableName);
  
  IRowFilter rowFilter = new IRowFilter() {
   @Override
   public boolean accept(IRowValueProvider rowValueProvider) {
    try {
     for(int i=0 ; i< expectColNames.length ; ++i){
      Object columnValue = rowValueProvider.getColumnValue(expectColNames[i]);
      if (!columnValue.equals(expectColVals[i]))
       return false;
     }
     return true;
    } catch (DataSetException ex) {
     ex.printStackTrace();
    }
    return false;
   }
  };
  RowFilterTable filteredRowsTable = new RowFilterTable(
    actualTable, rowFilter);
  return filteredRowsTable;
 }

使用方式:
現有XML DATA:


  
  
    

    
    
    
    

我只希望以XMLDATA建立出的ITable有條件:product == "17公司" and name=="tables"的資料,那麼就照以下方式呼叫:
   ITable expect = DBUnitUtilities.filterXmlDataCol("datasheet\\FactoryInfo.xml","FactoryInfo"
     , _dbunitConnection,new String[]{"name","product"},new String[]{"17公司","tales"} );


這樣就可以過濾囉~~

debug一下其實可以發現RowFilterTable並不是真的將資料給"過濾"掉了,只是將原先的Table給wrap後,然後帶入自行建立的IRowFilter(上述line 8~23),並在每一次巡迴column資料時以自定義的@ovverride accept()回傳true(資料保留) 或 false(資料移除)
回傳true的row index就會被保留在filteredRowIndexes這個List中囉。


p.s:
星期一就要交差幾乎會開天窗的我居然還在研究test.....只希望我這個堅持是對的....畢竟我真的不想再寫垃圾Code穩定度又差又無法擴充又不敢修改的爛東西了阿.........0rz...


參考:Filtering data sets and comparing results using DBUnit

2013年6月21日 星期五

dbunit初體驗 - 新增table data from existing xml data


首先,做一些setup工作
        
private MsSqlConnection _dbunitConnection;
 @Before
 public void setUp() throws Exception {
     _dbunitConnection = new MsSqlConnection(DBUnitUtilities.createHsqlDBConnection(), null);
      //do something setup..
 }

重點在這:
 IDataSet setup = DBUnitUtilities.getDataSet("datasheet\\Banner11.xml");
 DatabaseOperation.CLEAN_INSERT.execute(_dbunitConnection,setup);