Исключение ловли против броска для юнит-теста - PullRequest
0 голосов
/ 11 января 2020

В приведенном ниже коде проверяемое исключение выдается ClassToTest.throwsException (). Я предпочитаю добавить исключение throws к сигнатуре метода JUnit вместо того, чтобы переносить код, который выбрасывает исключение, в catch try. Это предпочтение основано только на том факте, что я считаю его более аккуратным. Есть ли здесь соглашение о кодировании, которое я нарушаю? Есть ли разница в функциональности с точки зрения тестирования при создании исключения по сравнению с try / catch в методе тестирования?

import org.junit.Test;

public class TestingClass {


    @Test
    public void getDataTest() throws Exception {

        new ClassToTest().throwsException();

    }

}

против:

import org.junit.Test;

public class TestingClass {


    @Test
    public void getDataTest() {

        try {
            new ClassToTest().throwsException();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

ClassToTest. java:

public class ClassToTest {

    public void throwsException() throws Exception {

    }
}

Ответы [ 2 ]

2 голосов
/ 12 января 2020

Если не ожидается, что будет выдан Exception, добавление блока try-catch к коду не принесет никаких дополнительных преимуществ. Хуже того, только добавление блока try-catch приведет к прохождению теста. Чтобы сделать тест неудачным, нужно добавить вызов к fail(), чтобы сделать тест на самом деле неудачным. Это возможный источник ошибки (если забыть позвонить fail()).


Для полноты картины я кратко расскажу о том, как проверить, что определенный Exception был брошен. Мне на ум приходят три подхода:

В первой попытке можно использовать try-catch, но с добавленным fail() в try -блоке, сразу после вызовов, которые должны бросить ожидаемый Exception. В catch -блоке можно было бы ожидать ожидаемый Exception. Все остальные Exception будут переброшены, и, следовательно, тест не пройден. У этого есть те же самые недостатки, что и у его родного брата, упомянутого выше.

Во-вторых, есть способ JUnit4, помечающий сам тест с @Test(expected = ExpectedException.class). На первый взгляд это кажется изящным, но нарушает структуру Given-When-Then тестов, часто приводя к тестам, выглядящим так:

@Test(expected = ArrayIndexOutOfBoundsException.class)
public void test() {
    // GIVEN
    final int[] array = new int[10];

    // WHEN
    final int value = array[10];

   // THEN: an ArrayIndexOutOfBoundsException should be thrown
}

, что нормально-i sh.

Наконец, есть способ JUnit5, заключающий фактический вызов в вызов assertThrows(...):

@Test(expected = ArrayIndexOutOfBoundsException.class)
void test() {
    // GIVEN
    final int[] array = new int[10];

    // WHEN
    final Exception e = assertThrows(ArrayIndexOutOfBoundsException.class,
            () -> {
                int value = array[10];
            }
    );

   // THEN
   assertTrue(e.getMessage().contains("10"));
}

Хотя это по-прежнему неправильно разделяет WHEN из THEN (я думаю, что это невозможно в Java), это дает дополнительное преимущество, позволяя проверять определенные c части Exception, например, сообщение 1 .

Я бы предложил эту статью в Baelung для дальнейшего чтения.


1 Это также возможно в JUnit4 , но это делается либо через явный блок try-catch, либо через очень громоздкий механизм, который окончательно нарушает структуру Given-When-Then. Для получения дополнительной информации, пожалуйста, проверьте статью в Baelung, упомянутой выше.

2 голосов
/ 12 января 2020

Просто добавьте предложение throws к объявлению метода и дайте исключению всплыть, как написано в FAQ по JUnit4 - Как мне написать тест, который завершается неудачно при возникновении непредвиденного исключения? :

Объявите исключение в предложении throws метода теста и не перехватывайте исключение в методе теста. Неопределенные исключения приведут к сбою теста с ошибкой.

Ниже приведен пример теста, который завершается неудачей при повышении IndexOutOfBoundsException:

@Test
public void testIndexOutOfBoundsExceptionNotRaised()
    throws IndexOutOfBoundsException {

    ArrayList emptyList = new ArrayList();
    Object o = emptyList.get(0);
}

IndexOutOfBoundsException может не будет хорошим примером здесь, так как это RuntimeException, но подход аналогичен для других исключений.

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