Java: Исключительное тестирование с Junit 3

Я хотел бы написать тест для IndexOutOfBoundsException. Имейте в виду, что мы должны использовать JUnit 3.

Мой код:

public boolean ajouter(int indice, T element) {
    if (indice < 0 || indice > (maListe.size() - 1)) {
        throw new IndexOutOfBoundsException();
    } else if (element != null && !maListe.contains(element)) {
        maListe.set(indice, element);
        return true;
    }
}

После некоторых исследований я обнаружил, что вы можете сделать это с помощью JUnit 4 с помощью @Test(expected = IndexOutOfBoundsException.class), но нет, где я нашел, как это сделать в JUnit 3.

Как проверить это с помощью JUnit 3?

Ответы

Ответ 1

Тестирование исключений в JUnit 3 использует этот шаблон:

try {
     ... code that should throw an exception ...

     fail( "Missing exception" );
} catch( IndexOutOfBoundsException e ) {
     assertEquals( "Expected message", e.getMessage() ); // Optionally make sure you get the correct message, too
}

fail() гарантирует, что вы получите сообщение об ошибке, если код не генерирует исключение.

Я использую этот шаблон в JUnit 4, так как обычно хочу убедиться, что правильные значения видны в сообщении об исключении, а @Test не может этого сделать.

Ответ 2

В принципе, вам нужно вызывать ваш метод и терпеть неудачу, если он не выбрасывает правильное исключение - или если он выбрасывает что-нибудь еще:

try {
  subject.ajouter(10, "foo");
  fail("Expected exception");
} catch (IndexOutOfBoundException expect) {
  // We should get here. You may assert things about the exception, if you want.
}

Ответ 3

Простое решение состоит в том, чтобы добавить улов try к unittest и позволить тесту сбой, если исключение не выбрано

public void testAjouterFail() {
  try {
    ajouter(-1,null);
    JUnit.fail();
  catch (IndexOutOfBoundException()) {
    //success
  }
}

Ответ 4

Одна вещь, которую вы можете сделать, это использовать логическое значение для запуска теста для завершения, а затем вы можете использовать assert для проверки исключения, которое было выбрано:

boolean passed = false;
try
{
    //the line that throws exception
    //i.e. illegal argument exception
    //if user tries to set the property to null:
    myObject.setProperty(null);
}
catch (IllegalArgumentException iaex)
{
    passed = true;
}
assertTrue("The blah blah blah exception was not thrown as expected"
              , passed);

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

Ответ 5

В методе тестирования вызовите ajouter() внутри блока try.. catch, указав значение indice, которое должно вызывать исключение, с

  • a catch, которое ловит IndexOutOfBoundsException: в этом случае вернитесь из вашего тестового метода и, таким образом, укажите пропуск.
  • второе предложение catch, которое ловит Throwable: в этом случае объявляет сбой (вызов fail()), потому что ошибочный вид исключения был брошен
  • после try.. catch объявить сбой (вызов fail()), потому что не было сделано никаких исключений.

Ответ 6

Расширение решения @Aaron с синтаксическим сахаром (статический импорт) позволяет писать:

    expected(MyException.class,
        new Testable() {
            public void test() {
            ... do thing that supposed to throw MyException ...
            }
        });

Testable похож на Runnable, который использует метку test(), бросающую Throwable.

public class TestHelper {
    public static void expected(Class<? extends Throwable> expectedClass, Testable testable) {
        try {
            testable.test();
            fail("Expected "+ expectedClass.getCanonicalName() +" not thrown.");
        } catch (Throwable actual) {
            assertEquals("Expected "+ expectedClass.getCanonicalName() +" to be thrown.", expectedClass, actual.getClass());
        }
    }

    interface Testable {
        public void test() throws Throwable;
    }
}

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