it-swarm.com.de

JUnit 5: Wie wird festgestellt, dass eine Ausnahme ausgelöst wird

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

Derzeit muss ich eine @Rule verwenden, um zu überprüfen, ob mein Test eine Ausnahme auslöst. Dies funktioniert jedoch nicht, wenn mehrere Methoden Ausnahmen in meinem Test erwarten.

90
steventrouble

Sie können assertThrows() verwenden, um mehrere Ausnahmen innerhalb desselben Tests zu testen. Mit Unterstützung für Lambdas in Java 8 ist dies die kanonische Methode, um Ausnahmen in JUnit zu testen.

Pro JUnit-Dokumente :

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

@Test
void exceptionTesting() {
    MyException thrown =
        assertThrows(MyException.class,
           () -> myObject.doThing(),
           "Expected doThing() to throw, but it didn't");

    assertTrue(thrown.getMessage().contains("Stuff"));
}
139
steventrouble

In Java 8 und JUnit 5 (Jupiter) können Ausnahmen wie folgt geltend gemacht werden . Verwendung von org.junit.jupiter.api.Assertions.assertThrows

public static <T erweitert Throwable> T assertThrows (Klasse <T> expectedType, Ausführbare ausführbare Datei)

Gibt an, dass die Ausführung der angegebenen ausführbaren Datei eine Ausnahme des erwartetenTyps auslöst und die Ausnahme zurückgibt.

Wenn keine Ausnahme ausgelöst wird oder 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);
            });
}

Bei diesem Ansatz wird die Funktionsschnittstelle Executable in org.junit.jupiter.api verwendet.

Verweisen :

64
prime

Sie haben es in JUnit 5 geändert (erwartet: InvalidArgumentException, actual: Invoked-Methode) und der Code sieht folgendermaßen aus:

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

Jetzt bietet Junit5 eine Möglichkeit, die Ausnahmen geltend zu machen

Sie können sowohl allgemeine als auch benutzerdefinierte Ausnahmen testen

Ein allgemeines Ausnahmeszenario:

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

Ein Beispiel zum Testen von CustomException finden Sie hier: Beispiel für einen Ausnahmecode

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

Ich denke, das ist ein noch einfacheres Beispiel

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

Wenn Sie get() für eine Option aufrufen, die eine leere ArrayList enthält, wird eine NoSuchElementException ausgelöst. assertThrows deklariert die erwartete Ausnahme und stellt einen Lambda-Lieferanten bereit (nimmt keine Argumente und gibt einen Wert zurück).

Danke an @prime für seine Antwort, auf die ich hoffentlich näher eingegangen bin.

6
JesseBoyd

Sie können assertThrows() verwenden. Mein Beispiel stammt aus den Dokumenten 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());
}
5
Will Humphreys

Eigentlich denke ich, dass in diesem speziellen Beispiel ein Fehler in der Dokumentation vorliegt. Die beabsichtigte Methode ist expectThrows

public static void assertThrows(
public static <T extends Throwable> T expectThrows(
1
Peter Isberg

Hier ist ein einfacher Weg.

@Test
void exceptionTest() {

   try{
        model.someMethod("invalidInput");
        fail("Exception Expected!");
   }
   catch(SpecificException e){

        assertTrue(true);
   }
   catch(Exception e){
        fail("wrong exception thrown");
   }

}

Es ist nur erfolgreich, wenn die erwartete Ausnahme ausgelöst wird.

0
kiwicomb123