Создание тестов со многими фиктивными объектами? - PullRequest
0 голосов
/ 14 ноября 2018

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

Я недавно прочитал Когда мне издеваться? , и я чувствую растерянность.

Давайте посмотрим на метод, который у меня есть (этопросто для иллюстрации проблемы)

@Override
protected void validate() throws WTException {
    Either<ImportError, RootFinderResult> rootPart = getDataValidator().getRootPart();
    if (rootPart.isLeft()) {
        addValidationMessage(ROOT_PART_NOT_FOUND);
    } else if (rootPart.isRight()) {
        getObjectsToValidate().forEach(Lambda.uncheckedBiConsumer((part, epmDocuments) -> {
            LocalizableMessage rootRevision = getRevision(part);

            Optional<EPMDocument> wrongRevisionEPM = epmDocuments.stream()
                    .filter(epmDocument -> !isSameRevision(rootRevision, epmDocument))
                    .findAny();

            wrongRevisionEPM.ifPresent(epmDocument -> addValidationMessage("blabla"));
        }));
    }
}

Для работы всех следующих методов необходимо подключение к серверу, в противном случае они будут выдавать ошибки

getDataValidator().getRootPart();
getRevision(part)
!isSameRevision(rootRevision, epmDocument))

Кроме того, я не могу создавать «реальные» объекты документов части или epm.Это также требует наличия подключения к серверу.


Итак, на данный момент, что я действительно хочу проверить, так это логика этой части кода

* 1023.*

Но чтобы проверить это, мне нужно смоделировать действительно много объектов

@Spy
@InjectMocks
private SameRevision sameRevision;
@Mock
private WTPartRelatedObjectDataValidator wTPartRelatedObjectDataValidator;
@Mock
private ValidationEntry validationEntry;
@Mock
private WTPart rootPart1, rootPart2;
@Mock
private EPMDocument epmDocument1, epmDocument2, epmDocument3;
@Mock
private Either<ImportError, RootFinderResult> rootPart;
@Mock
private LocalizableMessage rootPartRevisionOne, rootPartRevisionTwo;

, чтобы наконец я смог проверить логику:

@Test
@DisplayName("Should contain error message when part -> epms revisions are not the same")
void shoulHaveErrorMessagesWhenDifferentRevisions() throws Exception {
    doReturn(getMockObjectsToValidate()).when(sameRevision).getObjectsToValidate();

    doReturn(rootPart).when(liebherrWTPartRelatedObjectDataValidator).getRootPart();
    doReturn(false).when(rootPart).isLeft();
    doReturn(true).when(rootPart).isRight();

    doReturn(rootPartRevisionOne).when(sameRevision).getRevision(rootPart1);
    doReturn(rootPartRevisionTwo).when(sameRevision).getRevision(rootPart2);

    doReturn(true).when(sameRevision).isSameRevision(rootPartRevisionOne, epmDocument1);
    doReturn(false).when(sameRevision).isSameRevision(rootPartRevisionOne, epmDocument2);
    doReturn(true).when(sameRevision).isSameRevision(rootPartRevisionTwo, epmDocument3);

    validationEntry = sameRevision.call();

    assertEquals(1, validationEntry.getValidationMessageSet().size());
}

где

    doReturn(rootPart).when(liebherrWTPartRelatedObjectDataValidator).getRootPart();
    doReturn(false).when(rootPart).isLeft();
    doReturn(true).when(rootPart).isRight();

    doReturn(rootPartRevisionOne).when(sameRevision).getRevision(rootPart1);
    doReturn(rootPartRevisionTwo).when(sameRevision).getRevision(rootPart2);

можно переместить в @ BeforeEach.


Наконец-то у меня есть тест, и он работает.Это подтверждает то, что я хотел проверить, но для достижения этой цели мне пришлось приложить немало усилий, чтобы пройти через весь API, который нуждается во взаимодействии с сервером.

Как вы думаете, ребята, стоит ли создавать подобные тесты?Я предполагаю, что это широко открытая тема, потому что у многих новичков, которые пытаются войти в «тестовый мир», будет похожая проблема, поэтому, пожалуйста, не закрывайте тему из-за суждения, основанного на мнении, и оставьте свой отзыв по этой теме.

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

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

В вашем конкретном случае я бы тестировал на разных «слоях».

Например, методы: getDataValidator (). GetRootPart ();getRevision (part)! isSameRevision (rootRevision, epmDocument))

Они могут быть независимо протестированы, а в вашем случае просто высмеивать их результат, а это означает, что вам на самом деле не безразличны параметры, вы просто заботитесь о том, что происходитв случае определенного возвращаемого значения.

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

Надеюсь, теперь стало понятнее ...

0 голосов
/ 14 ноября 2018

Вы правы.Это большая попытка высмеять все эти зависимости.Позвольте мне остановиться на нескольких моментах, которые могут прояснить ситуацию:

  • Относитесь к написанию тестов как к инвестициям: Так что да, иногда для написания теста иногда требуется больше усилийчем написать актуальный код.Тем не менее, вы поблагодарите себя позже, когда внесете ошибку, и тесты смогут ее обнаружить.Наличие хороших тестов дает вам уверенность при изменении кода, что вы ничего не сломали, и если вы это сделали, ваши тесты найдут проблему.Это окупается со временем.

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

  • Подумайте о тестируемости при написании нового кода: Иногда бывает трудно избежать сложного фрагмента кода, который труднотестовое задание.Однако, как правило, этой ситуации можно избежать, если свести к минимуму количество зависимостей и написать тестируемый код.Например, если методу требуется еще 5 или 6 зависимостей, чтобы выполнить свою работу, то, вероятно, этот метод делает слишком много и может быть поврежден.То же самое можно сказать на уровне класса, модулей и т. Д.

0 голосов
/ 14 ноября 2018

Вы должны смоделировать другие зависимости, от которых зависит ваш класс, который будет тестироваться, и настроить поведение, которое вам нужно. Это необходимо сделать, чтобы протестировать ваш метод изолированным и не зависящим от классов thrirdparty. Вы можете написать приватные методы void, которые могут содержать ваше ложное поведение и использовать их в тестах, В аннотированном методе @BeforeEach можно смоделировать поведение, которое будет одинаковым во всех тестах, или смоделировать одинаковое поведение для всех тестов

В вашем методе, который является недействительным, вы можете иметь шпионские объекты, которые можно проверить, если они были вызваны как Mockito.verify ()

...