JUnit4 @Test (ожидается = MyException.class) VS try / catch - PullRequest
5 голосов
/ 15 июня 2011

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

В предыдущей статье о передовых методах, найденной в вики нашей компании, говорилось: «Не используйте try / catch, а используйте Junit4 @Test (Ожидается = MyException.class)», без дополнительной информации. Я не убежден.

Многие из наших пользовательских исключений имеют Enum для определения причины сбоя. В результате я бы предпочел увидеть тест вроде:

@Test
public void testDoSomethingFailsBecauseZzz() {
try{
   doSomething();
} catch(OurCustomException e){
   assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ, e.getFailure());
}
}

чем:

@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   doSomething();
}

когда doSomethig () выглядит так:

public void doSomething throws OurCustomException {
  if(Aaa) {
     throw OurCustomException(FailureEnum.AAA);
  } 
  if(Zzz) {
     throw OurCustomException(FailureEnum.ZZZ);
  }
  // ...
}

С другой стороны, я более чем убежден, что в некоторых случаях @Test (ожидается = blabla.class) - лучший выбор (например, когда исключение является точным и не может быть никаких сомнений относительно того, что его вызвало).

Я что-то здесь упускаю или мне нужно использовать try / catch при необходимости?

Ответы [ 6 ]

6 голосов
/ 15 июня 2011

Похоже, ваше перечисление используется в качестве альтернативы иерархии исключений? Возможно, если бы у вас была иерархия исключений, @Test(expected=XYZ.class) стал бы более полезным?

5 голосов
/ 15 июня 2011
  • Если вы просто хотите проверить, что было сгенерировано исключение определенного типа, используйте свойство expected аннотации.
  • Если вы хотите проверить свойства сгенерированного исключения (например, сообщениеили пользовательское значение элемента), перехватите его в тесте и сделайте утверждения.

В вашем случае кажется, что вы хотите, чтобы последнее (утверждало, что исключение имеет определенное значение FailureEnum); В использовании try/catch.

нет ничего плохого. Обобщение о том, что вы не должны использовать try / catch (интерпретируется как "never"), является пустым.

Джефф прав, хотя;организация вашей иерархии исключений является подозрительной.Тем не менее, вы, кажется, признаете это.:)

2 голосов
/ 15 июня 2011

Если вы хотите проверить необработанный тип исключения, тогда подходит метод expected.В противном случае, если вам нужно что-то протестировать на предмет исключения (и независимо от того, проверяется ли странность enum на содержание сообщения, это обычное явление), вы можете сделать попытку catch, но это немного устарело.Новый способ JUnit сделать это с MethodRule.Тот, что входит в API (ExpectedException), предназначен специально для тестирования сообщения, но вы можете легко просмотреть код и адаптировать эту реализацию для проверки на сбой enum s.

1 голос
/ 26 декабря 2012

Я сталкивался с этим при поиске способов обработки исключений.

Как уже упоминал @Yishai, предпочтительным способом ожидания исключений является использование правил JUnit и ExpectedException.

При использовании @Test(expected=SomeException.class) метод тестирования пройдет, если в каком-либо месте метода будет сгенерировано исключение.

Когда вы используете ExpectedException:

@Test
public void testException()
{
    // If SomeException is thrown here, the test will fail.
    expectedException.expect(SomeException.class);
    // If SomeException is thrown here, the test will pass.
}

Вы также можете проверить:

  • ожидаемое сообщение: ExpectedException.expectMessage();
  • ожидаемая причина: expectedException.expectCause().

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

1 голос
/ 15 июня 2011

В вашем особом случае вы хотите проверить (1), выбрасывается ли ожидаемое исключение type и (2), если номер ошибки правильный, потому что метод может выдавать одно и то же исключение с разными типами,

Для этого требуется проверка объекта исключения.Но вы можете придерживаться рекомендаций и , чтобы убедиться, что выброшено правильное исключение:

@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   try {
      doSomething();
   } catch (OurCustomException e) {
      if (e.getFailureEnum.equals(FailureEnum.ZZZ))  // use *your* method here
         throw e;

      fail("Catched OurCostomException with unexpected failure number: " 
        + e.getFailureEnum().getValue());  // again: your enum method here
   }
}

Этот шаблон съест неожиданное исключение исделать тест неудачным.

Редактировать

Изменил его, потому что я упустил очевидное: мы можем сделать тестовый случай неудачным и захватить сообщение.Итак, теперь: тест проходит, если ожидается ожидаемое исключение с ожидаемым кодом ошибки.Если тест не пройден из-за непредвиденной ошибки, мы можем прочитать код ошибки.

0 голосов
/ 25 июня 2012

Я сделал catch-исключение , потому что столкнулся с той же проблемой, что и вы, Stph.За исключением исключения catch ваш код может выглядеть так:

@Test
public void testDoSomethingFailsBecauseZzz() {
   verifyException(myObj, OurCustomException.class).doSomething();
   assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ,    
               ((OurCustomException)caughtException()).getFailure() ;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...