我遇到了TDD和不可能例外的問題。不可能例外的TDD
比方說,我們有一個名爲Foo(例如)類:
Class Foo {
public String getString(boolean shouldThrow) throws Exception {
if(shouldThrow) throw new Exception();
return "nonsense";
}
}
美孚僅在某些情況下拋出一個異常(爲簡單起見我把這裏的布爾)。
現在我想創建一個名爲Bar的類,它可以在不引發異常的情況下反轉Foo的字符串。
測試:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
assertEquals("esnesnon", bar.getReversedString());
}
}
我知道,布爾是假所有的時間。所以方法getReversedString()永遠不會拋出異常。但是因爲它不會引發異常,所以我不能寫一個斷言,這導致我在Bar內寫入try/catch塊。
所以測試將是這樣的:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
try {
assertEquals("esnesnon", bar.getReversedString());
} catch (Exception e) {
// ... will never happen
}
}
}
但是,這是不好的,因爲異常不會發生,我必須每次使用getReversedString(時間寫的try/catch塊)方法。 所以我想這個類是這樣的:
class Bar {
public String getReversedString() {
Foo foo = new Foo();
try {
String s = foo.getString(false);
} catch (Exception e) {
// will never happen...
}
// ... reverse string ...
return reversedString;
}
}
但由於異常將永遠不會發生,我不能寫爲的try/catch塊測試 - 所以我不能寫在try/catch-因爲TDD說「如果燈是紅色的,只能寫代碼」。
這是一個厄運循環...
我希望你有我! 謝謝!
謝謝!但是對於你的解決方案,我必須爲每個使用getReversedString()方法的方法添加「throws Exception」。由於例外將永遠不會被拋出,我認爲這是不好的做法。我需要一個測試,迫使我在Bar中寫入try/catch-block。 – 2014-12-27 17:49:46
「由於例外永遠不會拋出,我認爲這是不好的做法」 - 不,不是。如果引發異常,則測試失敗,就是這樣。而且,再次,不要拋出異常。拋出一個更具體的類型(最好是不會擴展'RuntimeException'的類型)。 – fge 2014-12-27 17:56:39
我認爲你是對的。也許這是最好的解決方案。順便說一下,在我的程序中它是一個IOException。 – 2014-12-27 17:59:19