雖然以前用easymock測試過Dao,但那些Dao的實現,要麼就hibernate,要麼就用spring,而這兩個框架的執行正確與否我們是不用關心的。JDBC是不是也這樣測試了。答案是肯定的。
這幾天要用存儲過程跟jdbc來做個項目,想想也有好長一段時間沒用過JDBC來做項目了。該復習復習了。
前陣子學了easymock,真好現在可以派上用場了。不過在測試的過程中還是遇到了不小問題,想來是自己基礎不好的緣故。
這次不TDD了,太麻煩了。
先看看我們要測試的代碼
Java 代碼
CallableStatementcstmt = null;
try {
cstmt = _conn.prepareCall("{call LUCK_LOAD_COMMON(?,?)}");
cstmt.setString(1, "1");
cstmt.registerOutParameter(2, Java.sql.Types.VARCHAR);
cstmt.executeUpdate();
return cstmt.getString(2);
} catch (Exception e) {
GxDebug.logException(e);
e.printStackTrace();
return null;
} finally {
if (cstmt != null)
try {
cstmt.close();
} catch (Exception e) {
}
}
代碼還挺長的。從上面的代碼我們知道我們必須mock兩個對象進去。一個是Connection, 一個是CallableStatementcstmt 。
好再看看我們的測試代碼
Java 代碼
conn.prepareCall("{call LUCK_LOAD_COMMON(?,?)}");
conControl.setReturnValue(cstmt);
conControl.replay();
cstmt.setString(1, "1");
cstmt.registerOutParameter(2, Java.sql.Types.VARCHAR);
cstmt.executeUpdate();
cstmtControl.setReturnValue(1);
cstmt.getString(2);
cstmtControl.setReturnValue("5,4,3");
cstmt.close();
cstmtControl.replay();
String rusult = dao.getNumber();
Assert.assertEquals("5,4,3", rusult);
conControl.verify();
cstmtControl.verify();
oh,my got!測試代碼比實現代碼還要多。這段代碼能執行嗎?
我想可以的。easymock的原理是記錄-回放的模式。
我想要做的工作是:
1,記錄你mock對象的工作記錄,比如上面的代碼我們mock對象的工作記錄是:
Java 代碼
conn.prepareCall("{call LUCK_LOAD_COMMON(?,?)}");
conControl.setReturnValue(cstmt);
cstmt.setString(1, "1");
cstmt.registerOutParameter(2, Java.sql.Types.VARCHAR);
cstmt.executeUpdate();
cstmtControl.setReturnValue(1);
cstmt.getString(2);
cstmtControl.setReturnValue("5,4,3");
cstmt.close();
如果你工作記錄的代碼要求有返回值的話,那麼你必須提供一個自定義的值給它,否則會報錯。比如上面的
cstmt.getString(2);
cstmtControl.setReturnValue("5,4,3"); //自己定義的返回值,用作以後的比較。
上面的是記錄操作,回放的時候,easymock會把記錄的操作跟你實際的代碼進行比較,如果裡面出了什麼差錯,那麼不好意思你的代碼有問題,請修正後再測試。
如果有興趣可以自己試下。
比如如果您
conn.prepareCall("{call LUCK_LOAD_COMMON(?,?)}");
修改為
conn.prepareCall("{call LUCK_LOAD_COMMON(?,?,?)}");
則出現的異常是:
junit.framework.AssertionFailedError:
Unexpected method call prepareCall("{call LUCK_LOAD_COMMON(?,?)}"):
prepareCall("{call LUCK_LOAD_COMMON(?,?)}"): expected: 0, actual: 1
prepareCall("{call LUCK_LOAD_COMMON(?,?,?)}"): expected: 1, actual: 0