Убедитесь, что метод был вызван и прерывание выполнения / игнорирование последующих сбоев - PullRequest
0 голосов
/ 27 июня 2018

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

Существует ли чистый способ подтверждения метода, который был вызван, и игнорировать все исключения, возникающие после этого? Возможно, какое-то блокирующее поведение при попадании в метод и прерывании / прохождении теста после этого?

Я думал, что смогу написать when(mock.methodIAmInterestedIn(any)).thenThrow(new RuntimeException("verified!")), а затем просто утверждать, что получаю правильное исключение (хотя оно будет заключено в другое). Это, вероятно, сработает, но это немного нечисто: скрывать то, что я действительно хочу проверить.

@Test
public void should_load_using_filename_in_config() {
    loader = new OrgUnitLoader(config, dbSupport.mockServices);
    config = mock(TestConfiguration.class);
    /* further mocking of the config needed if I am not to get an NPE */

    when(dao.orgUnitsAreLoaded()).thenReturn(false);

    // call the actual method
    loader.loadOrgUnits();

    verify(config, times(1)).getString(ORG_UNIT_DATA_FILE);
}

Может ли, например, использоваться CountdownLatch?

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Поскольку вы знаете, что ваш тестовый загрузчик / конфигурация не завершен, вы ожидаете, что метод в какой-то момент завершится с ошибкой. Учтите это в своем тесте:

@Test
public void should_load_using_filename_in_config() {
    loader = new OrgUnitLoader(config, dbSupport.mockServices);
    config = mock(TestConfiguration.class);
    /* further mocking of the config needed if I am not to get an NPE */

    when(dao.orgUnitsAreLoaded()).thenReturn(false);

    try {
        // call the actual method
        loader.loadOrgUnits();
        Assert.fail("Should fail as config is incomplete.");
    } catch (NullPointerException e) {
        verify(config, times(1)).getString(ORG_UNIT_DATA_FILE);
    }

}

РЕДАКТИРОВАТЬ (следующие комментарии)

Ловля только ожидаемого NPE исключает другие исключения. Если NPE будет брошено до того, как dao.orgUnitsAreLoaded() будет вызван, verify(...) потерпит неудачу. Вы заметите это.

Может быть, это не очень сложно, но это очень просто и легко ( KISS ) понять - даже позже, другим.

@ см. Junit что-то утверждает после ожидания и обработки исключения

0 голосов
/ 27 июня 2018

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

0 голосов
/ 27 июня 2018

Я хочу проверить первые биты логики. Мне все равно, что происходит в остальной части метода

Похоже, ваш тестируемый код не соответствует шаблону единой ответственности .

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


Есть два очевидных недостатка:

  1. Затем мне нужно было бы открыть SUT, превратив множество внутренних методов, которые, естественно, должны быть закрытыми, в методы с доступом к пакетам, чтобы иметь возможность их тестировать. - олигофрен

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

Мне кажется, что вся другая логика принадлежит другим классам, а не только отдельным методам в одном классе. Это следствие принципа Одинакового уровня абстракции , который мы должны применять как к классам, так и к методам. Эти новые классы действительно обеспечивают по крайней мере package private доступ к их интерфейсу.

  1. Я был бы очень тесно связан с внутренним пространством SUT, но, думаю, я уже этим занимаюсь ... - oligofren

Этот "тесно связанный" может существовать только в вашей голове, зная реальную реализацию. Тот факт, что вам нужно разделить код для тестирования, показывает, что код менее ограничен, как вы думаете.

Я полагаю, что во всех решениях по модульному тестированию есть определенный прагматизм (код только для тестирования, открытие, ...). - олигофрен

Существует довольно простое правило о юнит-тестировании, которое избегает всех этих "прагматических решений":

UnitTest не проверяет код , UnitTest проверяет общедоступное наблюдаемое поведение где public означает: возвращаемые значения и связь с зависимостями .

Нет места для "прагматических решений". Единственное решение: каково ожидаемое поведение CUT ?

...