Тестирование на множественные исключения с аннотациями JUnit 4 - PullRequest
25 голосов
/ 11 сентября 2009

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

    @Test(expected=IllegalStateException.class)

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

Ответы [ 7 ]

22 голосов
/ 11 сентября 2009

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

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

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

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

12 голосов
/ 20 сентября 2009

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

С 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 для вас невозможно, вы должны написать пустой блочный тест вида

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

}

3 голосов
/ 22 июня 2012

Использование catch-исключение :

// 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);

}
2 голосов
/ 13 сентября 2017

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

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})
0 голосов
/ 26 июля 2016
@Test(expected=Exception.class)

Это вызовет все возможные исключения.

0 голосов
/ 11 сентября 2009

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

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

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

Держите это коротким и простым.

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

Привет

0 голосов
/ 11 сентября 2009

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

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

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