2016-10-26 40 views
37

有沒有更好的方法來斷言一個方法在JUnit 5中拋出異常?JUnit 5:如何聲明異常被拋出?

目前,我必須使用一個@Rule來驗證我的測試是否引發異常,但這對於預期多個方法在我的測試中拋出異常的情況不起作用。

回答

45

您可以使用assertThrows(),它允許您在同一測試中測試多個例外。通過支持Java 8中的lambda表達式,這可能會成爲在JUnit中測試異常的標準方法。

JUnit docs

import static org.junit.jupiter.api.Assertions.assertThrows; 

... 

@Test 
void exceptionTesting() { 
    Executable closureContainingCodeToTest =() -> throw new IllegalArgumentException("a message"); 

    assertThrows(IllegalArgumentException.class, closureContainingCodeToTest, "a message"); 
} 
+1

從一所古老的學校「我對Junit5不太瞭解,對Java8可能不夠了解......」這看起來很奇怪。你介意添加更多的解釋嗎?比如「哪個部分存在被測試的實際」生產代碼「......這應該會丟掉」? – GhostCat

+0

'() - >'_points_到一個接受零參數的lambda表達式。因此,期望拋出異常的「生產代碼」在代碼塊_pointed to_(即花括號內的'throw new ...'語句)中。 –

+1

通常,lambda表達式將與測試中的主體(SUT)進行交互。換句話說,直接拋出像上面這樣的異常僅僅是爲了演示的目的。 –

1

其實我覺得這是對這個特殊的例子在文檔中一個錯誤。這意的方法是expectThrows

public static void assertThrows(
public static <T extends Throwable> T expectThrows(
+0

「刪除了不推薦使用Assertions.assertThrows()方法的Assertions.expectThrows()方法。」 –

6

他們已經在JUnit的5改變了它(預期:InvalidArgumentException,實際:調用的方法)和代碼看起來像這樣:

@Test 
public void wrongInput() { 
    Throwable exception = assertThrows(InvalidArgumentException.class, 
      ()->{objectName.yourMethod("WRONG");}); 
} 
0

您可以使用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()); 
} 
6

在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); 
      }); 
} 

這一方法將使用功能接口Executableorg.junit.jupiter.api

參見:

3

現在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()); 
} 
+0

明顯!謝謝 – HariKishore

4

我覺得這是一個更簡單的例子

List<String> emptyList = new ArrayList<>(); 
Optional<String> opt2 = emptyList.stream().findFirst(); 
assertThrows(NoSuchElementException.class,() -> opt2.get()); 

上調用get()包含一個空的選項ArrayList將會拋出一個NoSuchElementExceptionassertThrows聲明預期的異常並提供一個lambda供應商(不接受任何參數並返回一個值)。

感謝@prime他的回答,我希望闡述。