單元測試的時候遇到的一個問題
開始的時候這個單元測試在eclipse和mvn中都是跑不過的(原因資料庫裡插入了一個非空列),然後把這個修改好,問題就開始出現了。
在eclipse中跑出來的結果是非常振奮人心的
但是通過mvn test跑出來的結果確是:
遇到了這個問題,第一反應覺得是不是因為檔案沒儲存或者因為eclipse中裝了svn外掛程式導致的檔案不同步的問題。刪除eclipse中的項目,重新clean install整個pivot,在mvn eclipse:eclipse,再匯入eclipse,但是沒有任何效果。
然後去仔細看了一下test的日誌,發現其中有很多的Exception打出來了,覺得是不是這裡出現問題了。
DEBUG util.SQLHelper - Could not retrieve the 'isAutoIncrement' property because not yet running on Java 1.5 - defaulting to NO. Table=CREDIT_CMT_APPLY, Column=IS_GUAR_VALIDjava.sql.SQLException: ��Ч�������� 註:這裡的意思大概意思就是SQl索引失效at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:379)at org.dbunit.util.SQLHelper.createColumn(SQLHelper.java:348)at org.dbunit.database.DatabaseTableMetaData.getColumns(DatabaseTableMetaData.java:331)at org.dbunit.database.DatabaseTableMetaData.toString(DatabaseTableMetaData.java:402)at java.lang.String.valueOf(String.java:2826)at java.lang.StringBuffer.append(StringBuffer.java:219)
不過這個日誌的層級是Debug,貌似不應該影響測試結果啊。不過還是去確定一下這個有沒有影響比較好。然後找到日誌打出的地方如下,發現這裡只是去判斷了一下jdk是1.5進行一些操作,不是也不會有什麼影響。
接著去看maven輸出來的test結果,發現錯誤資訊是:
junit.framework.AssertionFailedError:null
這是個什麼意思阿?然後去找了一下,發現原因是在JUnit 4.4 以前的版本預設出錯後不會拋出額外提示資訊,如:
assertTrue( s.indexOf("developer") > -1 || s.indexOf("Works") > -1 );如果該斷言出錯,只會拋出無用的錯誤資訊,如:junit.framework.AssertionFailedError:null。如果想在出錯時想列印出一些有用的提示資訊,必須得程式員另外手動寫,如:
assertTrue( "Expected a string containing 'developer' or 'Works'", s.indexOf("developer") > -1 || s.indexOf("Works") > -1 );public static final Column createColumn(ResultSet resultSet,384 IDataTypeFactory dataTypeFactory, boolean datatypeWarning) 385 throws SQLException, DataTypeException 386 {387 ...395 // This is only available since Java 5 - so we ca try it and if it does not work default it396 String isAutoIncrement = Column.AutoIncrement.NO.getKey();397 try {398 isAutoIncrement = resultSet.getString(23);399 }400 catch(SQLException e){401 if(logger.isDebugEnabled())402 logger.debug("Could not retrieve the 'isAutoIncrement' property because not yet running on Java 1.5 - defaulting to NO. " +403 "Table=" + tableName + ", Column=" +columnName, e);404 // Ignore this one here405 }406 407 ...428 }Unit 4.4 以前的版本預設出錯後不會拋出額外提示資訊,如:assertTrue( s.indexOf("developer") > -1 || s.indexOf("Works") > -1 );如果該斷言出錯,只會拋出無用的錯誤資訊,如:junit.framework.AssertionFailedError:null。如果想在出錯時想列印出一些有用的提示資訊,必須得程式員另外手動寫,如:assertTrue( "Expected a string containing 'developer' or 'Works'", s.indexOf("developer") > -1 || s.indexOf("Works") > -1 );既然讓寫,那就寫一下試試。
assertTrue("number="+number,number > 0);註:原來代碼裡面的一個判斷,想讓它輸出一些資訊,但是發現並沒有輸出這個,看來不是在這裡出的問題。剩下的代碼中可能出問題的一共就只有兩行。
setUpDataSet("dbunit/complaintSet.xml");Long number = this.complaintApplyDAO.insert(complaintApplyDO);然後通過一個個注釋的方法確定到問題在setUpDataSet這一行。
進一步定位發現是初始化資料的設定檔中出錯了,其中一共有7條資料,通過排除法確定,問題在下面這個代碼中。
<credit_cmt_apply id="10007" COMPLAINT_Id="1234567890" C_MEMBER_ID="test100" A_MEMBER_ID="test200"TYPE ="cash_no_delivery" FULL_TYPE="cash_no_delivery" SUBJECT ="subject" TRADE_ID="1001001" TRADE_TYPE="alipay" A_TEL="010-85356521" A_MOBILE_PHONE="13054541254"GMT_CREATE="2009-12-28"GMT_PRE_INTERPOSE="2010-1-26" GMT_INTERPOSE="2009-12-28" GMT_ACCEPT="2009-12-28" GMT_RESOLVE="2009-12-28" STATUS="NEW" RESULT="NEW"COMPANY_NAME="compay" CONTENT="content" TRADE_URL="http://china.alibaba.com"IS_TRANSIT="Y" IS_GUAR_VALID="Y" IS_ELIGIBLE="Y" GMT_MODIFIED="2009-12-28" A_TEL_AREA="010" SUB_TYPE="subType" GMT_ARBIT_BEGIN="2009-12-28" GMT_ARBIT_END="2009-12-28"ARBIT_OPERATOR="test" />
經驗證,問題原因是GMT_PRE_INTERPOSE="2010-1-26"這個出現的,如果將2010-1-26改成2010-01-26,則eclipse中和maven中都可以正確了。
到這裡雖然確定了問題出在哪,但是進一步的思路確不是太明確了,上網找也沒什麼頭緒。然後就開始求助於大家,最後在曉軍那裡得到答案,原來jdk1.6.0_18中對這個日期的處理進行了一些改動。不同版本的代碼,發現改動確實在這裡。
原來的java.sql.Date.ValueOf的代碼如下:
public static Date valueOf(String s) { int year; int month; int day; int firstDash; int secondDash; if (s == null) throw new java.lang.IllegalArgumentException(); firstDash = s.indexOf('-'); secondDash = s.indexOf('-', firstDash+1); if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) { ... } else { throw new java.lang.IllegalArgumentException(); } return new Date(year, month, day); }新的中的是:
if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length()-1)) { String yyyy = s.substring(0, firstDash); String mm = s.substring(firstDash + 1, secondDash); String dd = s.substring(secondDash + 1); if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH && dd.length() == DAY_LENGTH) { ... } } if (d == null) { throw new java.lang.IllegalArgumentException(); } return d;在之前的時候並不去判斷年月日的長度,在新的中加入了對年份月份日的強制判斷,必須是4-2-2,否則拋出異常。
最後問題定位到maven和eclipse中的java環境版本不同的問題。
通過查看確定maven中環境是:(我自己裝的)
Java version: 1.6.0_20Java home: /usr/lib/java/jdk1.6.0_20/jre
eclipse的環境是:(貌似是系統預設的一個)