Тестирование Android JUnit ... Как ожидать исключения - PullRequest
46 голосов
/ 06 мая 2011

Я пытаюсь написать несколько тестов, используя встроенную платформу тестирования Android в Android. У меня проблема с тестом, в котором я ожидаю исключения. В JUnit аннотация для метода тестирования будет:

@Test(expected = ArithmeticException.class)

Однако в Android этот тест не выполняется с ArithmeticException.

Я понимаю, что реализация Android является лишь подмножеством JUnit 3 и даже не допускает аннотацию @Test (должна быть @SmallTest, @MediumTest или @LargeTest, и ни одна из них не допускает ожидаемый = параметр ".), но это выглядит довольно значительным тестом, и похоже, что фреймворку для тестирования Android не хватало бы, если бы у него не было этой функции.

Примечание: Я проверил это, добавив банку JUnit в проект и добавив аннотации к моим методам тестирования. Для меня имеет смысл, почему аннотации были бы полностью проигнорированы, потому что платформа Android (бегун?) Не ищет эту аннотацию и просто игнорирует ее. По сути, я просто ищу «правильный» способ сделать это в рамках.

Ответы [ 3 ]

66 голосов
/ 06 мая 2011

Стандартная идиома Junit 3 для этого вида теста была:

public void testThatMethodThrowsException()
{
  try
  {
    doSomethingThatShouldThrow();
    Assert.fail("Should have thrown Arithmetic exception");
  }
  catch(ArithmeticException e)
  {
    //success
  }
}
29 голосов
/ 26 января 2015

Теперь JUnit4 доступен через Android SDK (см. android-test-kit )

Обновление : теперь официально на d.android.com :

AndroidJUnitRunner - это новый разделенный тестовый прогон для Android, которая является частью библиотеки тестирования поддержки Android и может быть загружается через репозиторий поддержки Android. Новый бегун содержит все улучшения GoogleInstrumentationTestRunner и добавляет больше Особенности:

  • Поддержка JUnit4
  • Реестр инструментов для доступа к инструментам, контексту и аргументам пакета
  • Тестовые фильтры @SdkSupress и @ requireDevice
  • Тайм-ауты теста
  • Шардинг тестов
  • Поддержка RunListener для подключения к жизненному циклу тестового запуска
  • Механизм мониторинга активности ActivityLifecycleMonitorRegistry

Итак, Тестирование исключений в стиле JUnit4 с использованием ожидаемой аннотации:

@Test(expected= IndexOutOfBoundsException.class) 
public void empty() { 
     new ArrayList<Object>().get(0); 
}

или ожидаемые правила исключения:

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

@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
    List<Object> list = new ArrayList<Object>();

    thrown.expect(IndexOutOfBoundsException.class);
    thrown.expectMessage("Index: 0, Size: 0");
    list.get(0); // execution will never get past this line
}

также возможно.

Более подробную информацию о настройке библиотеки поддержки тестирования см. В официальной документации .

2 голосов
/ 16 июля 2018

Я искал несколько хороших решений, однако, ни одно из решений меня не удовлетворяло. Итак, я создал свой собственный.

public final void assertThrows(VoidFunction v, Class<? extends Exception> e) {
    try {
        v.call();
    } catch (Exception ex) {
        if (!ex.getClass().equals(e)) {
            Assert.fail();
        }
        // Do nothing, basically succeeds test if same exception was thrown.
        return;
    }

    // Fails if no exception is thrown by default.
    Assert.fail();
}

Где VoidFunction - простой интерфейс:

@FunctionalInterface
public interface VoidFunction {
    void call();
}

Используется следующим образом (например):

@Test
public void testFoo() {
    assertThrows(() -> foo.bar(null)), NullPointerException.class);
    assertThrows(() -> foo.setPositiveInt(-5)), IllegalArgumentException.class);
    assertThrows(() -> foo.getObjectAt(-100)), IndexOutOfBoundsException.class);
    assertThrows(new VoidFunction() {
            @Override
            public void call() {
                foo.getObjectAt(-100);
            }
        }, IndexOutOfBoundsException.class); // Success
    assertThrows(new VoidFunction() {
                @Override
                public void call() {
                    throw new Exception();
                }
            }, NullPointerException.class); // Fail

}

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

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