Протестируйте переопределенный метод внутреннего класса с помощью JUnit и Mockito - PullRequest
0 голосов
/ 16 января 2020

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

public void fetchLocalData(final String source, final ObservableEmitter<String> destination) {
   final List<String> options = Arrays.asList("recursive","allFiles","includeDir");
   // This class comes from a package
   final DirScan dirscan = new DirScan(source, options) {
       @Override
       protected Action getResult(final String result) {
           destination.onNext(result);
           return Action.Continue;
       }
   };
   dirscan.scan();
   destination.onComplete();
}

Я пытался:

    DirScan scanner = mock(DirScan.class);
    when(scanner.scan()).thenReturn("one").thenReturn("two");

Это не сработало. Что мне не хватает? Как мне потребуется рефакторинг, чтобы сделать этот тестируемый?

1 Ответ

0 голосов
/ 16 января 2020

Если вы хотите заменить dirscan на макет (или шпиона), вам нужно реорганизовать свой класс, чтобы он был зависимостью или параметром. В качестве альтернативы вы можете использовать PowerMockito функциональность whenNew.

Предположим, вы изменили свой класс, и вместо String source вы предоставляете объект DirScan в качестве параметра. Вам понадобится какой-то метод создания для dirscan в другом месте (это может быть static метод).

final List<String> options = Arrays.asList("recursive","allFiles","includeDir");

public DirScan createDirScan(String source) {

   // This class comes from a package
   final DirScan dirscan = new DirScan(source, options) {
       @Override
       protected Action getResult(final String result) {
           destination.onNext(result);
           return Action.Continue;
       }
   };

   return dirscan;
}
public void fetchLocalData(final DirScan dirscan, final ObservableEmitter<String> destination) {
    dirscan.scan();
    destination.onComplete();
}

Судя по вашему вопросу, вы хотите проверить взаимодействие с пунктом назначения объект, поэтому вы не хотите издеваться над объектом dirscan (потому что если вы это сделаете, никакого взаимодействия не будет). Возможно, вы захотите использовать spy и заменить только метод getResult.

Теперь в своем тесте вы можете просто передать spy для объекта dirscan и определить его поведение с помощью thenAnswer.

final ObservableEmitter<String> destination = ...

DirScan dirscan = Mockito.spy(createDirScan(source, destination));

Mockito.when(dirscan.getResult(Mockito.any(String.class))).thenAnswer((Answer<Action>) invocation -> {
    String result = invocation.getArgument(0);
    destination.onNext(result);

    return Action.Continue;
});

classUnderTest.fetchLocalData(dirscan, destination);

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

Реальный объект должен работать, чтобы этот тест имел ценность, так что вы можете также проверить реальный вещь.

...