Поймать универсальное исключение в Java? - PullRequest
34 голосов
/ 11 июня 2010

Мы используем JUnit 3 на работе, а аннотации ExpectedException нет. Я хотел добавить утилиту в наш код, чтобы обернуть это:

 try {
     someCode();
     fail("some error message");
 } catch (SomeSpecificExceptionType ex) {
 }

Итак, я попробовал это:

public static class ExpectedExceptionUtility {
  public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
     try {
        block.exceptionThrowingCode();
        fail(message);
    } catch (T ex) {
    }
  }
}

Однако Java не может использовать универсальные типы исключений в блоке catch, я думаю.

Как я могу сделать что-то подобное, обходя ограничение Java?

Есть ли способ проверить, что переменная ex имеет тип T?

Ответы [ 6 ]

28 голосов
/ 11 июня 2010

Вы можете передать объект Class и проверить это программно.

public static <T extends Exception> void checkForException(String message, 
        Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
    try {
       block.exceptionThrowingCode();
   } catch (Exception ex) {
       if ( exceptionType.isInstance(ex) ) {
           return;
       } else {
          throw ex;  //optional?
       }
   }
   fail(message);
}

//...
checkForException("Expected an NPE", NullPointerException.class, //...

Я не уверен, хотите ли вы переворота или нет; повторное отбрасывание в равной степени провалило бы / провалило бы тест, но семантически я бы этого не сделал, поскольку в основном это означает, что «мы не получили ожидаемое исключение» и, следовательно, представляет собой ошибку программирования вместо ошибки среды тестирования.

4 голосов
/ 11 июня 2010

Я понимаю побуждение попытаться упростить идиому теста исключений, но серьезно: нет. Каждый возможный выбор, который вам придет, - это лекарство, которое хуже болезни. Особенно Чепуха @UpectedException JUnit 4! Это слишком умное интегрированное решение, требующее, чтобы все узнали, как оно работает, в отличие от простого самоочевидного кусочка обычного кода Java. Хуже того, это не дает вам возможности обернуть только ту часть теста, которую вы ожидаете вызвать исключение, поэтому, если на более раннем этапе установки выдается то же исключение, ваш тест пройдет, даже если ваш код не работает.

Я мог бы написать длинную диатрибу об этом здесь (извините за нехватку времени), так как у нас было долгое обсуждение этой проблемы среди инженеров Java здесь, в Google, и согласие было, что эти сумасшедшие решения стоят того. Привыкайте пробовать / ловить, это действительно не так уж и плохо.

0 голосов
/ 25 мая 2016

Дженерики не являются типами.Они не шаблоны.Это проверки типов времени компиляции в Java.Блоки исключений ловят по типу.Вы можете поймать (исключение e) или даже поймать (Throwable e), а затем разыграть по мере необходимости.

0 голосов
/ 23 января 2015

Предложение Catch с параметром типа невозможно:
http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch

0 голосов
/ 11 июня 2010

Вы также можете использовать интегрированную среду разработки, которая поддерживает живой шаблон (например, IntellJ IDEA , например, ), и назначить ярлык, например ee -> [tab], который вставляет команду try / catch / ignore и позволяет вам ввести правильный один.

нравится http://img80.imageshack.us/img80/433/capturadepantalla201006j.png

нравится http://img641.imageshack.us/img641/6733/capturadepantalla201006w.png

0 голосов
/ 11 июня 2010

Ну, вы можете просто поймать Исключение и сбросить, если это не ожидаемое Исключение.Хотя хорошая практика кодирования обычно диктует, что путь успеха кода не должен определяться Исключением, поэтому вы, возможно, захотите переосмыслить свой дизайн.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...