有沒有更好的方法來斷言一個方法在JUnit 5中拋出異常?JUnit 5:如何聲明異常被拋出?
目前,我必須使用一個@Rule來驗證我的測試是否引發異常,但這對於預期多個方法在我的測試中拋出異常的情況不起作用。
有沒有更好的方法來斷言一個方法在JUnit 5中拋出異常?JUnit 5:如何聲明異常被拋出?
目前,我必須使用一個@Rule來驗證我的測試是否引發異常,但這對於預期多個方法在我的測試中拋出異常的情況不起作用。
您可以使用assertThrows()
,它允許您在同一測試中測試多個例外。通過支持Java 8中的lambda表達式,這可能會成爲在JUnit中測試異常的標準方法。
import static org.junit.jupiter.api.Assertions.assertThrows;
...
@Test
void exceptionTesting() {
Executable closureContainingCodeToTest =() -> throw new IllegalArgumentException("a message");
assertThrows(IllegalArgumentException.class, closureContainingCodeToTest, "a message");
}
其實我覺得這是對這個特殊的例子在文檔中一個錯誤。這意的方法是expectThrows
public static void assertThrows(
public static <T extends Throwable> T expectThrows(
「刪除了不推薦使用Assertions.assertThrows()方法的Assertions.expectThrows()方法。」 –
他們已經在JUnit的5改變了它(預期:InvalidArgumentException,實際:調用的方法)和代碼看起來像這樣:
@Test
public void wrongInput() {
Throwable exception = assertThrows(InvalidArgumentException.class,
()->{objectName.yourMethod("WRONG");});
}
您可以使用assertThrows()
。我的例子是從文檔http://junit.org/junit5/docs/current/user-guide/
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
....
@Test
void exceptionTesting() {
Throwable exception = assertThrows(IllegalArgumentException.class,() -> {
throw new IllegalArgumentException("a message");
});
assertEquals("a message", exception.getMessage());
}
在Java 8和JUnit 5(木星),我們可以斷言例外如下考慮。 使用org.junit.jupiter.api.Assertions.assertThrows
公共靜態<Ť延伸的Throwable>ŤassertThrows(<類T> expectedType, 可執行可執行)
斷言所提供的可執行的執行投expectedType並返回的一個異常例外。
如果沒有拋出異常,或者拋出了不同類型的異常,則此方法將失敗。
如果您不想對異常實例執行額外的檢查,只需忽略返回值即可。
@Test
public void itShouldThrowNullPointerExceptionWhenBlahBlah() {
assertThrows(NullPointerException.class,
()->{
//do whatever you want to do here
//ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null);
});
}
這一方法將使用功能接口Executable
在org.junit.jupiter.api
。
參見:
現在Junit5提供了一種斷言例外
您可以測試一般例外和自定義例外
的一般例外情形:
ExpectGeneralException.java
public void validateParameters(Integer param) {
if (param == null) {
throw new NullPointerException("Null parameters are not allowed");
}
}
ExpectGeneralExceptionTest.java
@Test
@DisplayName("Test assert NullPointerException")
void testGeneralException(TestInfo testInfo) {
final ExpectGeneralException generalEx = new ExpectGeneralException();
NullPointerException exception = assertThrows(NullPointerException.class,() -> {
generalEx.validateParameters(null);
});
assertEquals("Null parameters are not allowed", exception.getMessage());
}
你可以找到一個樣本在這裏測試CustomException:assert exception code sample
ExpectCustomException.java
public String constructErrorMessage(String... args) throws InvalidParameterCountException {
if(args.length!=3) {
throw new InvalidParameterCountException("Invalid parametercount: expected=3, passed="+args.length);
}else {
String message = "";
for(String arg: args) {
message += arg;
}
return message;
}
}
ExpectCustomExceptionTest.java
@Test
@DisplayName("Test assert exception")
void testCustomException(TestInfo testInfo) {
final ExpectCustomException expectEx = new ExpectCustomException();
InvalidParameterCountException exception = assertThrows(InvalidParameterCountException.class,() -> {
expectEx.constructErrorMessage("sample ","error");
});
assertEquals("Invalid parametercount: expected=3, passed=2", exception.getMessage());
}
明顯!謝謝 – HariKishore
我覺得這是一個更簡單的例子
List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class,() -> opt2.get());
上調用get()
包含一個空的選項ArrayList
將會拋出一個NoSuchElementException
。 assertThrows
聲明預期的異常並提供一個lambda供應商(不接受任何參數並返回一個值)。
感謝@prime他的回答,我希望闡述。
從一所古老的學校「我對Junit5不太瞭解,對Java8可能不夠了解......」這看起來很奇怪。你介意添加更多的解釋嗎?比如「哪個部分存在被測試的實際」生產代碼「......這應該會丟掉」? – GhostCat
'() - >'_points_到一個接受零參數的lambda表達式。因此,期望拋出異常的「生產代碼」在代碼塊_pointed to_(即花括號內的'throw new ...'語句)中。 –
通常,lambda表達式將與測試中的主體(SUT)進行交互。換句話說,直接拋出像上面這樣的異常僅僅是爲了演示的目的。 –