我寫單元測試我們的主要產品,並有一個擔憂:如何區分語義對損壞的單元測試
- 測試失敗,因爲他們測試了錯誤(錯誤被發現和非迴歸測試它的實例)
- 測試失敗,因爲測試的另一個意想不到的部分失敗(因爲測試是錯誤的或未知的bug出現)
這是第一個,我們對JUnit的斷言框架當然,但是我們對第二個有什麼?例如:我的單元測試正在測試c()不會拋出MyException,而是執行c()我需要先執行一個()然後b(),它們都可以拋出MyException(),所以我會寫:
@Test
public void testC() {
a();
Object forC = b();
try {
c(forC);
} catch (MyException e) {
Assert.fail("....");
}
}
但是然後我需要處理可以由a或b拋出的MyException,並且還處理了forC不應該爲null的事實。做這個的最好方式是什麼?
- Catch MyException拋出a或b和Assert.fail,但a和b沒有通過這個測試測試,所以對我來說,他們不應該被標記爲失敗時測試失敗。也許他們以後失敗,因爲在這個時候我們應該做b(); a()不是a(); b();.
- 讓testC拋出MyException,這樣測試將失敗並顯示「MyException」,但這是誤導,因爲MyException不會告訴測試寫錯了。所有的測試都會失敗,每個都有自己的異常。在這種情況下,如果forC爲空(也沒有語義),我還需要拋出類似NullPointerException的內容。
- 將a和b拋出的異常捕獲幷包裝成異常,告訴測試可能是錯誤的,就像TestCorruptedException。但是我不能在jUnit中找到這樣的異常,所以它們不會被jUnit識別(這對我來說沒問題)。另外我需要從我所有的單元測試中知道這個異常,當然這些單元測試分爲多個模塊,項目等等。所以這是可行的,但是增加了依賴性。
你會怎樣解決這個問題?如上所述,我可能會參加第二場比賽,但我對此並不滿意。
正確的,我的問題是確實是c是緊密相連的一個()因爲它們的真名是startTransaction()和commit(),所以它們具有公共結構和鎖。你的回答告訴我,我正在進行集成測試,所以我註定要失敗,只能祈求a和b是正確的。它太過努力讓他們獨立,但這對我來說是解決問題的方法。 – jolivier 2012-07-13 17:00:54
這就是像[Spring的註解驅動的事務管理](http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#transaction- declarative-annotations)這樣的聲明式事務管理真正發光的地方。您的方法c()可以拋棄對startTransaction()和commit()的調用,讓您可以自由地對其進行測試。 c()不會在意它是否在事務中,你會在調用方法中捕獲任何異常。這裏是一個[小型教程](http://www.javacodegeeks.com/2011/09/spring-declarative-transactions-example.html)感興趣 – Brad 2012-07-13 20:36:34