JUnit 5: Как утверждать, что исключение выбрасывается?


есть ли лучший способ утверждать, что метод вызывает исключение в JUnit 5?

В настоящее время я должен использовать правило @для проверки того, что мой тест создает исключение, но это не работает для случаев, когда я ожидаю, что несколько методов будут создавать исключения в моем тесте.

8 69

8 ответов:

можно использовать assertThrows(), что позволяет тестировать несколько исключений в рамках одного теста. С поддержкой лямбд в Java 8 это, вероятно, станет каноническим способом проверки исключений в 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");
}

в Java 8 и JUnit 5 (Jupiter) мы можем утверждать для исключений следующее. Используя org.junit.jupiter.api.Assertions.assertThrows

общественная статический Т assertThrows(класса 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.

см. :

они изменили его в JUnit 5 (ожидаемый: InvalidArgumentException, фактический: вызванный метод) и код выглядит так:

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

теперь 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 здесь:утвердить код исключения образец

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

Я думаю, что это еще более простой пример

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

вызов get() на необязательном содержании пустого ArrayList бросит NoSuchElementException. assertThrows объявляет ожидаемое исключение и предоставляет поставщика лямбда (не принимает аргументов и возвращает значение).

спасибо @prime за его ответ, который я надеюсь, подробно остановился.

можно использовать 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());
}

на самом деле я думаю, что есть ошибка в этом конкретном примере документации. Метод, который предназначен является expectThrows

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

вот простой способ.

@Test
void exceptionTest() {

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

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

}

это происходит только тогда, когда исключение, которое вы ожидаете, выбрасывается.