2016-10-26 2 views
37

Есть ли лучший способ утверждать, что метод генерирует исключение в JUnit 5?JUnit 5: Как утверждать, что исключение бросается?

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

ответ

45

Вы можете использовать assertThrows(), что позволяет протестировать несколько исключений в рамках одного и того же теста. При поддержке lambdas в 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"); 
} 
+1

Из старой школы «Я не знаю много о Junit5 и, вероятно, недостаточно о Java8» ... это выглядит довольно странно. Не могли бы вы добавить еще несколько объяснений; как «в какой части есть фактический« производственный код »под тестом ... который должен был выбраться»? – GhostCat

+0

'() ->' _points_ к выражению лямбда, которое принимает нулевые аргументы. Таким образом, «производственный код», который, как ожидается, генерирует исключение, находится в блоке кода _pointed to_ (т. Е. Оператор 'throw new ...' в фигурных скобках). –

+1

Как правило, лямбда-выражение будет взаимодействовать с испытуемым объектом (SUT). Другими словами, прямое исключение, подобное выше, предназначено только для демонстрационных целей. –

1

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

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

"Утилит устаревшего метода Assertions.expectThrows() в пользу Assertions.assertThrows()." –

6

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

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

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

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

общественный статический < T расширяет Throwable> T 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.

См:

3

Теперь 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 exception code sample

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

очевидно! благодаря – HariKishore

4

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

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

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

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

Смежные вопросы