l

2013年4月11日 星期四

JUnit4的例外測試

Apr. 10 21:39~23:12

不知道鄉民們有沒有幫例外處理撰寫過單元測試,在JUnit3的年代要測試程式碼是否有丟出預期的例外物件,首先用try statement把會丟出例外的程式碼包覆住,接著在catch clause裡面捕捉例外物件。如果測試案例能夠捕捉到預期的例外物件,就算通過,否則就是測試失敗。請參考以下範例,假設鄉民們要測試User這個物件,下面這個例子就是要測試當User物件的生日欄位不完整的時候,User物件將會丟出InvalidFormatException,並且顯示「Day is invalid」這個例外訊息。

螢幕快照 2013-04-11 下午1.53.30

 

測試案例執行通過,表示InvalidFormatEception真的有被丟出來。

螢幕快照 2013-04-11 下午2.13.38

 

JUnit4加入一個annotation來簡化例外處理的測試,如下圖所示。

螢幕快照 2013-04-11 下午1.55.23

程式看起來簡單許多,只要在第29行加上@Test (expected=InvalidFormatException.class)這個annotation就可以了。但以這個例子來講,出現InvalidFormatException有可能是生日中的年、月或是日提供不完整的資料。若要能夠進一步測試例外訊息是否如預期,這樣的方法便無法達到目的。

使用Rule

JUnit4.7新增Rule這個強大的功能,直接加入了ExpectedException這條內建Rule之後,不僅能提高測試涵蓋率也能滿足程式碼簡化的需求,請看下面的程式碼。

螢幕快照 2013-04-11 下午1.56.33

 

上面的程式碼第35~36行先宣告一條ExpectedException的內建Rule,接著在測試案例中前兩行(40~41行)指定該測試案例所預期的例外物件以及例外訊息,最後兩行才是待測程式。

如果要對例外訊息內容做模糊比對,可以呼叫JUnitMatchers物件的靜態函式,請看下面程式範例。

clip_image008

***

自己撰寫Matcher

如果要測試例外物件的其他屬性或是做更進階的比對,可以自己實作Matcher。下面範例實作一個NullMatcher類別,這個NullMatcher類別判斷例外訊息中是否有出現null這個字,程式碼如下。

clip_image012

 

使用的時候直接在expect()裡面把NullMatcher()給new出來就可以了。如果鄉民們的例外物件中有其他欄位的資料,透過自己實作Matcher的方法,可以有彈性的比對這些自訂欄位。

clip_image010

***

最後提醒一下,這個例子是在最新版的Eclipse 4.2.2中使用預設的JUnit4完成。目前最新版的JUnit4對於JUnitMatchers與Matcher類別的用法有點改變,因此如果鄉民們使用最新版的JUnit4會發生程式無法編譯的問題,請小心服用挑眉質疑

***

友藏內心獨白:JUnit4真的加了很多東西啊。

沒有留言:

張貼留言