JUnit 5: Как утверждать, что исключение выбрасывается?
есть ли лучший способ утверждать, что метод вызывает исключение в JUnit 5?
В настоящее время я должен использовать правило @для проверки того, что мой тест создает исключение, но это не работает для случаев, когда я ожидаю, что несколько методов будут создавать исключения в моем тесте.
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
.см. :
- http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions
- http://junit.org/junit5/docs/5.0.0-M2/api/org/junit/jupiter/api/Executable.html
- http://junit.org/junit5/docs/5.0.0-M4/api/org/junit/jupiter/api/Assertions.html#assertThrows-java.lang.Class-org.junit.jupiter.api.function.Executable-
они изменили его в 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"); } }
это происходит только тогда, когда исключение, которое вы ожидаете, выбрасывается.