JUnit 5: Как утвердить исключение?
Есть ли лучший способ утверждать, что метод генерирует исключение в JUnit 5?
В настоящее время я должен использовать @Rule для проверки того, что мой тест выдает исключение, но это не работает для случаев, когда я ожидаю, что несколько методов будут генерировать исключения в моем тесте.
Ответы
Ответ 1
Вы можете использовать assertThrows()
, который позволяет тестировать несколько исключений в одном тесте. С поддержкой лямбд в Java 8 это, вероятно, станет каноническим способом проверки исключений в JUnit.
Согласно документам JUnit:
import static org.junit.jupiter.api.Assertions.assertThrows;
...
@Test
void exceptionTesting() {
Executable closureContainingCodeToTest =
// This represents production code that is expected to throw
() -> throw new IllegalArgumentException("a message");
assertThrows(IllegalArgumentException.class,
closureContainingCodeToTest,
"We expect the code under test to throw, but it didn't");
}
Ответ 2
В Java 8 и JUnit 5 (Юпитер) мы можем утверждать об исключениях следующим образом. Использование org.junit.jupiter.api.Assertions.assertThrows
public static <T extends Throwable> T assertThrows (класс <T> Ожидаемый тип, исполняемый файл)
Утверждает, что выполнение предоставленного исполняемого файла вызывает исключение ожидаемого типа и возвращает исключение.
Если не сгенерировано исключение или если сгенерировано исключение другого типа, этот метод завершится ошибкой.
Если вы не хотите выполнять дополнительные проверки экземпляра исключения, просто проигнорируйте возвращаемое значение.
@Test
public void itShouldThrowNullPointerExceptionWhenBlahBlah() {
assertThrows(NullPointerException.class,
()->{
//do whatever you want to do here
//ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null);
});
}
Этот подход будет использовать Executable
org.junit.jupiter.api
функционального интерфейса в org.junit.jupiter.api
.
См.:
Ответ 3
Они изменили его в JUnit 5 (ожидается: InvalidArgumentException, actual: invoked method), и код выглядит следующим образом:
@Test
public void wrongInput() {
Throwable exception = assertThrows(InvalidArgumentException.class,
()->{objectName.yourMethod("WRONG");} );
}
Ответ 4
Теперь 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 здесь: пример кода исключения assert
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());
}
Ответ 5
Я думаю, что это еще более простой пример
List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class, () -> opt2.get());
Вызов get()
для необязательного NoSuchElementException
содержащего пустой ArrayList
вызовет NoSuchElementException
. assertThrows
объявляет ожидаемое исключение и предоставляет лямбда-поставщика (не принимает аргументов и возвращает значение).
Спасибо @prime за его ответ, который я надеюсь развить.
Ответ 6
Вы можете использовать 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());
}
Ответ 7
На самом деле, я думаю, что ошибка в документации для этого конкретного примера. Предполагаемый метод - ожидатьThrows
public static void assertThrows(
public static <T extends Throwable> T expectThrows(
Ответ 8
Вот простой способ.
@Test
void exceptionTest() {
try{
model.someMethod("invalidInput");
fail("Exception Expected!");
}
catch(SpecificException e){
assertTrue(true);
}
catch(Exception e){
fail("wrong exception thrown");
}
}
Успешно, только когда вы ожидаете исключения.