[英]Try Catch block works but test assertThrows fail (Junit 5)
我正在嘗試遵循本教程JUnit 5:如何斷言引發異常?
我使用Java 10,IntelliJ 2018和Junit 5。
我制作了一個計算器應用程序,將2個分數相加。 它檢查輸入的分母是否為0。
當我運行測試時,異常消息將被打印出來“未定義的數學表達式”,但我的IDE卻顯示“預計將拋出java.lang.Throwable,但未拋出任何異常”。 我認為我的代碼范圍有問題嗎? 我是新手,請客氣。 我在下面提供了代碼和測試:
public class Calculator {
public static int[] calculate (int firstNumerator, int firstDenominator, int secondNumerator, int secondDenominator) {
String exceptionMessage = "Undefined Math Expression";
int resultNumerator;
int resultDenominator;
int[] result = new int[2];
resultNumerator = (firstNumerator * secondDenominator) +
(secondNumerator * firstDenominator);
resultDenominator = firstDenominator * secondDenominator;
try {
if (resultDenominator == 0) {
throw (new Throwable(exceptionMessage));
} else {
result[0] = resultNumerator;
result[1] = resultDenominator;
}
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return result;
}
}
考試:
class CalculatorTest {
@Test
void denominatorContainsZero() {
assertThrows(Throwable.class, () -> {
Calculator.calculate(0,0,0,0);
});
}
}
Throwable
被try catch
塊try catch
,因此Junit無法訪問它。 嘗試刪除try catch
塊。
這里的誤解似乎是JUnit實際可以看到的。
JUnit不是神奇的:它只是普通的舊Java。 在您的方法內部看不到它們在做什么。 它所看到的就是任何其他代碼在執行一個方法時所看到的:返回值和未捕獲的異常(以及方法的任何副作用,如果它們對調用代碼可見)。
從調用者的角度來看,您的方法不會引發異常:在內部,它會引發異常,但會捕獲並處理該異常。
如果希望JUnit測試拋出了異常,則無需捕獲該異常。
拋出異常然后自己捕獲並處理該異常永遠不是(*)正確的事情。 重點是什么? 您可以簡單地做您要處理的事情,而不會引發異常。 拋出異常非常昂貴,因為需要捕獲整個堆棧跟蹤。
Throwable
永遠不是(*)正確的拋出異常。 這是返回Object
“等效”異常:它不會將有關異常的類型信息傳達給調用方,調用方則必須做大量工作來嘗試處理該異常; 或者,更現實的是,應該自己傳播它。 如果您確實需要拋出(而不是捕獲)異常,則IllegalArgumentException
是正確的拋出異常的地方。
Throwable
很少是正確的選擇。 Throwable
是Exception
和Error
的超類型,因此您可能無意中捕獲了一個Error
,例如OutOfMemoryError
,不應捕獲它,因為除了使程序崩潰之外,沒有其他合理的操作。 趕上最具體的類型; 這也意味着您應該拋出最具體的類型(或者至少是適合抽象的類型)。
(*)這是“從不”,如“好,在有限的情況下,適當的情況”中所述。 但是除非您了解這些是什么,否則請不要。
您實際上並沒有引發異常,而是在捕獲異常。 為此,您應該刪除try catch塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.