开始的时候这个单元测试在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_VALID java.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 it 396 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 here 405 } 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_20 Java home: /usr/lib/java/jdk1.6.0_20/jre