web-dev-qa-db-fra.com

JUnit 5: Comment affirmer qu'une exception est levée?

Existe-t-il un meilleur moyen d’affirmer qu’une méthode lève une exception dans JUnit 5?

Actuellement, je dois utiliser un @Rule afin de vérifier que mon test lève une exception, mais cela ne fonctionne pas dans les cas où plusieurs méthodes jetteront des exceptions dans mon test.

90
steventrouble

Vous pouvez utiliser assertThrows() , qui vous permet de tester plusieurs exceptions dans le même test. Prise en charge de lambdas dans Java 8, il s'agit du moyen canonique de tester les exceptions dans JUnit.

Par le JUnit docs :

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

Dans Java 8 et JUnit 5 (Jupiter), nous pouvons affirmer les exceptions comme suit: . Utiliser org.junit.jupiter.api.Assertions.assertThrows

public static <T étend Throwable> T assertThrows (Classe <T> type attendu, Exécutable exécutable)

Assure que l'exécution de l'exécutable fourni lève une exception du type attendu et renvoie l'exception.

Si aucune exception n'est levée, ou si une exception d'un type différent est levée, cette méthode échouera.

Si vous ne souhaitez pas effectuer de vérifications supplémentaires sur l'instance d'exception, ignorez simplement la valeur de retour.

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

Cette approche utilisera l'interface fonctionnelle Executable dans org.junit.jupiter.api.

Référer :

64
prime

Ils l'ont changé dans JUnit 5 (attendu: InvalidArgumentException, méthode actuelle: invoquée) et le code ressemble à celui-ci:

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

Maintenant, Junit5 fournit un moyen d'affirmer les exceptions

Vous pouvez tester les exceptions générales et les exceptions personnalisées. 

Un scénario d'exception général:

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

Vous pouvez trouver un exemple pour tester CustomException ici: exemple de code d'assert d'exception

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

Je pense que ceci est un exemple encore plus simple

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

L'appel de get() sur une option contenant une ArrayList vide lancera une NoSuchElementException. assertThrows déclare l'exception attendue et fournit un fournisseur lambda (ne prend aucun argument et retourne une valeur).

Merci à @prime pour sa réponse, que j’ai développée avec espoir.

6
JesseBoyd

Vous pouvez utiliser assertThrows(). Mon exemple est tiré de docs 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

En fait, je pense qu'il y a une erreur dans la documentation de cet exemple particulier. La méthode envisagée est expectThrows

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

Voici un moyen facile.

@Test
void exceptionTest() {

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

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

}

Il ne réussit que lorsque l'exception que vous attendez est levée.

0
kiwicomb123