Как вы утверждаете, что в тестах JUnit 4 выбрасывается определенное исключение? - PullRequest
1834 голосов
/ 01 октября 2008

Как я могу использовать JUnit4 идиоматически для проверки того, что какой-то код вызывает исключение?

Хотя я, конечно, могу сделать что-то вроде этого:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

Я вспоминаю, что есть аннотация или Assert.xyz или что-то , что гораздо менее хитро и гораздо более в духе JUnit для подобных ситуаций.

Ответы [ 33 ]

5 голосов
/ 06 июня 2013

Просто создайте Matcher, который можно включать и выключать, например:

public class ExceptionMatcher extends BaseMatcher<Throwable> {
    private boolean active = true;
    private Class<? extends Throwable> throwable;

    public ExceptionMatcher(Class<? extends Throwable> throwable) {
        this.throwable = throwable;
    }

    public void on() {
        this.active = true;
    }

    public void off() {
        this.active = false;
    }

    @Override
    public boolean matches(Object object) {
        return active && throwable.isAssignableFrom(object.getClass());
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("not the covered exception type");
    }
}

Чтобы использовать это:

добавить public ExpectedException exception = ExpectedException.none();, то:

ExceptionMatcher exMatch = new ExceptionMatcher(MyException.class);
exception.expect(exMatch);
someObject.somethingThatThrowsMyException();
exMatch.off();
5 голосов
/ 09 марта 2015

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

try{
   methodThatThrowMyException();
   Assert.fail("MyException is not thrown !");
} catch (final Exception exception) {
   // Verify if the thrown exception is instance of MyException, otherwise throws an assert failure
   assertTrue(exception instanceof MyException, "An exception other than MyException is thrown !");
   // In case of verifying the error message
   MyException myException = (MyException) exception;
   assertEquals("EXPECTED ERROR MESSAGE", myException.getMessage());
}
5 голосов
/ 08 декабря 2016

В JUnit 4 или более поздней версии вы можете протестировать исключения следующим образом

@Rule
public ExpectedException exceptions = ExpectedException.none();


это предоставляет множество функций, которые можно использовать для улучшения наших тестов JUnit.
Если вы видите приведенный ниже пример, я проверяю 3 вещи на исключение.

  1. Тип создаваемого исключения
  2. Сообщение об исключении
  3. Причина исключения


public class MyTest {

    @Rule
    public ExpectedException exceptions = ExpectedException.none();

    ClassUnderTest classUnderTest;

    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
    }

    @Test
    public void testAppleisSweetAndRed() throws Exception {

        exceptions.expect(Exception.class);
        exceptions.expectMessage("this is the exception message");
        exceptions.expectCause(Matchers.<Throwable>equalTo(exceptionCause));

        classUnderTest.methodUnderTest("param1", "param2");
    }

}
4 голосов
/ 22 мая 2015

В дополнение к сказанному NamShubWriter убедитесь, что:

  • Экземпляр ExpectedException - public ( Связанный вопрос )
  • ExpectedException не создается, например, в методе @Before. Этот пост ясно объясняет все тонкости порядка исполнения JUnit.

Делай не делай это:

@Rule    
public ExpectedException expectedException;

@Before
public void setup()
{
    expectedException = ExpectedException.none();
}

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

3 голосов
/ 18 июля 2018

Я рекомендую библиотеку assertj-core для обработки исключений в тесте junit

В Java 8, вот так:

//given

//when
Throwable throwable = catchThrowable(() -> anyService.anyMethod(object));

//then
AnyException anyException = (AnyException) throwable;
assertThat(anyException.getMessage()).isEqualTo("........");
assertThat(exception.getCode()).isEqualTo(".......);
2 голосов
/ 06 апреля 2018

Решение Junit4 с Java8 заключается в использовании этой функции:

public Throwable assertThrows(Class<? extends Throwable> expectedException, java.util.concurrent.Callable<?> funky) {
    try {
        funky.call();
    } catch (Throwable e) {
        if (expectedException.isInstance(e)) {
            return e;
        }
        throw new AssertionError(
                String.format("Expected [%s] to be thrown, but was [%s]", expectedException, e));
    }
    throw new AssertionError(
            String.format("Expected [%s] to be thrown, but nothing was thrown.", expectedException));
}

Использование тогда:

    assertThrows(ValidationException.class,
            () -> finalObject.checkSomething(null));

Обратите внимание, что единственным ограничением является использование final ссылки на объект в лямбда-выражении. Это решение позволяет продолжить тестовые утверждения вместо ожидаемых значений на уровне метода, используя решение @Test(expected = IndexOutOfBoundsException.class).

1 голос
/ 29 октября 2016

Взять, к примеру, вы хотите написать Junit для указанного ниже фрагмента кода

public int divideByZeroDemo(int a,int b){

    return a/b;
}

public void exceptionWithMessage(String [] arr){

    throw new ArrayIndexOutOfBoundsException("Array is out of bound");
}

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

 @Rule
public ExpectedException exception=ExpectedException.none();

private Demo demo;
@Before
public void setup(){

    demo=new Demo();
}
@Test(expected=ArithmeticException.class)
public void testIfItThrowsAnyException() {

    demo.divideByZeroDemo(5, 0);

}

@Test
public void testExceptionWithMessage(){


    exception.expectMessage("Array is out of bound");
    exception.expect(ArrayIndexOutOfBoundsException.class);
    demo.exceptionWithMessage(new String[]{"This","is","a","demo"});
}
0 голосов
/ 16 апреля 2019
    @Test(expectedException=IndexOutOfBoundsException.class) 
    public void  testFooThrowsIndexOutOfBoundsException() throws Exception {
         doThrow(IndexOutOfBoundsException.class).when(foo).doStuff();  
         try {
             foo.doStuff(); 
            } catch (IndexOutOfBoundsException e) {
                       assertEquals(IndexOutOfBoundsException .class, ex.getCause().getClass());
                      throw e;

               }

    }

Вот еще один способ проверить правильность сгенерированного метода или нет.

0 голосов
/ 08 августа 2018
try {
    my method();
    fail( "This method must thrwo" );
} catch (Exception ex) {
    assertThat(ex.getMessage()).isEqual(myErrormsg);
}
0 голосов
/ 09 ноября 2017

Существует два способа написания тестового примера

  1. Аннотировать тест с исключением, которое выдается методом. Как то так @Test(expected = IndexOutOfBoundsException.class)
  2. Вы можете просто перехватить исключение в тестовом классе, используя блок try catch и подтвердить сообщение, которое выдается из метода в тестовом классе.

    try{
    }
    catch(exception to be thrown from method e)
    {
         assertEquals("message", e.getmessage());
    }
    

Я надеюсь, что это отвечает на ваш запрос Счастливого обучения ...

...