Подтвердить что ты не робот

Тестирование нескольких исключений с помощью аннотаций JUnit 4

Можно ли проверить несколько исключений в одном JUnit unit test? Я знаю, что для одного исключения можно использовать, например

    @Test(expected=IllegalStateException.class)

Теперь, если я хочу проверить другое исключение (скажем, NullPointerException), можно ли это сделать в той же аннотации, другой аннотации или мне нужно полностью написать еще unit test?

4b9b3361

Ответ 1

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

например. (в псевдокоде)

try {
   badOperation();
   /// looks like we succeeded. Not good! Fail the test
}
catch (ExpectedException e) {
   // that fine
}
catch (UnexpectedException e) {
   // that NOT fine. Fail the test
}

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

Ответ 2

Это невозможно в аннотации.

С JUnit 4.7 вы можете использовать новое правило ExpectedException

public static class HasExpectedException {
    @Interceptor
    public ExpectedException thrown= new ExpectedException();

    @Test
    public void throwsNothing() {
    }

    @Test
    public void throwsNullPointerException() {
         thrown.expect(NullPointerException.class);
         throw new NullPointerException();
    }

    @Test
    public void throwsNullPointerExceptionWithMessage() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage("happened?");
        throw new NullPointerException("What happened?");
    }
}

Подробнее см.


Если вам не удалось выполнить обновление до JUnit 4.7, вам нужно написать голый unit test формы

public test() {
    try {
        methodCall(); // should throw Exception
        fail();
    }
    catch (Exception ex) {
        assert((ex instanceof A) || (ex instanceof B) || ...etc...);
        ...
    }

}

Ответ 3

Используйте catch-exception:

// test 
public void testDo() {

   // obj.do(1) must throw either A or B
   catchException(obj).do(1);
   assert caughtException() instanceof A
       || caughtException() instanceof B;

   // obj.do(2) must throw A but not SubclassOfA
   catchException(obj).do(2);
   assert caughtException() instanceof A
       && !(caughtException() instanceof SubclassOfA);

}

Ответ 4

Хотя это невозможно с JUnit 4, это возможно, если вы переключитесь на TestNG, что позволяет писать

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})

Ответ 5

Как вы ожидаете, что "ожидаемые" будут работать? Метод может вызывать только одно исключение.

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

Ответ 6

держать тесты максимально простыми и короткими. цель JUnit-Test - проверить только одну простую функциональность или один единственный способ отказа.

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

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

держите его коротким и простым.

у вас может быть 30-40 методов тестирования для одного единственного метода... действительно ли это имеет значение?

рассматривает

Ответ 7

@Test(expected=Exception.class)

который выдает все Expections