2016-10-26 4 views
37

Gibt es eine bessere Möglichkeit zu behaupten, dass eine Methode eine Ausnahme in JUnit 5 auslöst?JUnit 5: Wie wird eine Ausnahme ausgelöst?

Derzeit muss ich eine @Rule verwenden, um zu überprüfen, dass mein Test eine Ausnahme auslöst, aber dies funktioniert nicht für die Fälle, in denen ich mehrere Methoden erwarte, Ausnahmen in meinem Test zu werfen.

Antwort

45

Sie können assertThrows() verwenden, mit dem Sie mehrere Ausnahmen innerhalb des gleichen Tests testen können. Mit der Unterstützung von Lambdas in Java 8 wird dies wahrscheinlich die kanonische Methode sein, um in JUnit auf Ausnahmen zu testen.

Per den 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

Von einer alten Schule "Ich weiß nicht viel über Junit5 und wahrscheinlich nicht genug über Java8" ... das sieht ziemlich bizarr aus. Würde es Ihnen etwas ausmachen, weitere Erklärungen hinzuzufügen? wie "welcher Teil dort ist der tatsächliche 'Produktionscode', den man testen sollte ... der werfen sollte?" – GhostCat

+0

'() ->' _points_ zu einem Lambda-Ausdruck, der keine Argumente akzeptiert. Somit ist der "Produktionscode", von dem erwartet wird, dass er die Ausnahme auslöst, in dem Codeblock _pointed to_ (d. H. Der Anweisung "throw new ..." in den geschweiften Klammern). –

+1

Typischerweise würde die Lambda-Expression mit dem zu testenden Subjekt (SUT) interagieren. Mit anderen Worten, das direkte Auslösen einer Ausnahme wie oben ist nur zu Demonstrationszwecken gedacht. –

1

Eigentlich denke ich, es ein Fehler für dieses Beispiel in der Dokumentation. Das Verfahren, das dazu bestimmt ist expectThrows ist

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

"Die veraltete Methode Assertions.expectThrows() wurde zugunsten von Assertions.assertThrows() entfernt." –

6

Sie es in JUnit geändert haben 5 (erwartet: InvalidArgumentException, tatsächlich: aufgerufene Methode) und Code sieht aus wie diese:

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

Sie assertThrows() verwenden können . Mein Beispiel ist aus der docs genommen 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

In Java 8 und JUnit 5 (Jupiter) wir für Ausnahmen geltend machen können wie folgt. org.junit.jupiter.api.Assertions.assertThrows

public static < T Verwenden erstreckt Throwable> T assertThrows (Klasse < T> expectedType, Executable ausführbaren)

Asserts dass die Ausführung der gelieferten ausführbaren eine Ausnahme des expectedType wirft und kehrt die Ausnahme.

Wenn keine Ausnahme ausgelöst wird oder wenn eine Ausnahme eines anderen Typs ausgelöst wird, schlägt diese Methode fehl.

Wenn Sie keine zusätzlichen Prüfungen für die Ausnahmeinstanz durchführen möchten, ignorieren Sie einfach den Rückgabewert.

@Test 
public void itShouldThrowNullPointerExceptionWhenBlahBlah() { 
    assertThrows(NullPointerException.class, 
      ()->{ 
      //do whatever you want to do here 
      //ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null); 
      }); 
} 

Dieser Ansatz wird die funktionale Schnittstelle Executable in org.junit.jupiter.api verwenden.

Siehe:

3

Jetzt Junit5 bietet eine Möglichkeit, die Ausnahmen zu behaupten

Sie sowohl allgemeine Ausnahmen und maßgeschneiderte Ausnahmen testen können

Eine allgemeine Ausnahme Szenario:

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

Sie eine Probe finden CustomException testen hier: 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

offensichtlich! Vielen Dank – HariKishore

4

Ich denke, dies ist ein noch einfacheres Beispiel

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

Aufruf get() auf ein optionales, das einen leeren ArrayList enthält, wirft einen NoSuchElementException. assertThrows deklariert die erwartete Ausnahme und stellt einen Lambda-Lieferanten zur Verfügung (nimmt keine Argumente und gibt einen Wert zurück).

Dank @prime für seine Antwort, die ich hoffentlich weiter ausgearbeitet habe.

Verwandte Themen