測試方法的主體通過驗證assertion(斷言)對被測方法進行詢問。例如,在toString()實施的測試方法中,你希望確認該方法已經(jīng)對時間的設(shè)定進行了很好的說明(對于UNIX系統(tǒng)來說,初問世的時間為1970年1月1日的午夜)。要實施assertion,你可以使用Junit框架提供的assertion方法。這些方法在該框架的junit.framework.Assert類中被實施,并且可以在你的測試中被訪問,這是因為Assert是TestCase的父類。這些方法可與Java中的關(guān)鍵字assert(是在J2EE 1.4中新出現(xiàn)的)相比。一些assertion方法可以檢查原始類型(如布爾型、整型等)之間或?qū)ο笾g是否相等(利用equals()方法檢查兩個對象是否相等)。其他assertion方法檢查兩個對象是否相同、一個對象是否為"空"或"非空",以及一個布爾值(通常由一個表達式生成)是"真"還是"假"。在表 1中對這些方法進行了總結(jié)。
對于那些采用浮點類型或雙精度類型參數(shù)的assertion,存在一個第三種方法,即采用一個delta值作為參數(shù)進行比較。另外還要注意,assertEquals()和assertSame()方法一般不會產(chǎn)生相同的結(jié)果。(兩個具有相同值的字符串可以不相同,因為它們是兩個具有不同內(nèi)存地址的不同對象。)因此,assertEquals()將會驗證assertion的有效性,而assertSame()則不會。注意,對于表 1 中的每個assertion方法,你還有一種選擇,是引入另一個參數(shù),如果assertion失敗,該參數(shù)會給出一條解釋性消息。例如,assertEquals(int 期望值, int 實際值)可以與一個諸如assertEquals(字符串消息,int期望值,int實際值)的消息一起使用。
當一個assertion失敗時,該assertion方法會拋出一個AssertFailedError或ComparisonFailure。AssertionFailedError由java.lang.Error繼承而來,因此你不必在測試方法的throws語句中對其進行聲明。而ComparisonFailure由AssertionFailedError繼承而來,因此你也不必對其進行聲明。因為當一個assertion失敗時會在測試方法中拋出一個錯誤,所以后面的assertion將不會繼續(xù)運行。框架捕捉到這些錯誤并認定該測試已經(jīng)失敗后,會打印出一條說明錯誤的消息。這個消息由assertion生成,并且被傳遞到assertion方法(如果有的話)。
現(xiàn)在將下面一行語句添加到testIsoDate()方法的末尾:
assertEquals("This is a test",1,2);
現(xiàn)在編譯并運行測試:
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest
.F.
Time: 0,348
There was 1 failure:
1) testIsoDate(IsoDateTest)junit.framework
.AssertionFailedError: This is a test expected:<1> but was:<2>
at IsoDateTest.testIsoDate
(IsoDateTest.java:29)
FAILURES!!!
Tests run: 2, Failures: 1, Errors: 0
JUnit為每個已處理的測試打印一個點,顯示字母"F"來表示失敗,并在assertion失敗時顯示一條消息。此消息由你發(fā)送到assertion方法的注釋和assertion的結(jié)果組成(自動生成)。從這里可以看出assertion方法的參數(shù)順序?qū)τ谏傻南⒎浅V匾。第一個參數(shù)是期望值,而第二個參數(shù)則是實際值。
如果在測試方法中出現(xiàn)了某種錯誤(例如,拋出了一個異常),該工具會將其顯示為一個錯誤(而不是由assertion失敗而產(chǎn)生的一個"失敗"),F(xiàn)在對IsoDateTest類進行修改,以將前面增加的一行語句用以下語句代替:
throw new Exception("This is a test");
然后編譯并運行測試:
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest
.E.
Time: 0,284
There was 1 error:
1) testIsoDate(IsoDateTest)java.lang.
Exception: This is a test at IsoDate
Test.testIsoDate(IsoDateTest.java:30)
FAILURES!!!
Tests run: 2, Failures: 0, Errors: 1
該工具將該異常顯示為一個錯誤。因此,一個錯誤表示一個錯誤的測試方法,而不是表示一個錯誤的測試實施。
Assert類還包括一個fail()方法(該版本帶有解釋性消息),該方法將通過拋出AssertionFailedError來中斷正在運行的測試。當你希望一個測試失敗而不會調(diào)用一個判定方法時,fail()方法是非常有用的。例如,如果一段代碼應(yīng)當拋出一個異常而未拋出,那么可以調(diào)用fail()方法使該測試失敗,方法如下:
public void testIndexOutOfBounds() {
try {
ArrayList list=new ArrayList();
list.get(0);
fail("IndexOutOfBoundsException
not thrown");
} catch(IndexOutOfBoundsException e) {}
}