Вызов реального метода с использованием Mockito - PullRequest
0 голосов
/ 10 июля 2020

Я использую JDK 11 и пружинный ботинок. Я реализую API отдыха и имею 3 уровня:

  • контроллер
  • уровень обслуживания
  • уровень доступа к данным

У меня были классы против интерфейсов на уровне доступа к данным и не имел никакого интерфейса на уровне сервиса.

Я написал интеграционные тесты, используя Mock Mvc, Mockito и др. c, чтобы проверить весь путь для каждой точки , выставленный контроллером. Это не было проблемой, пока я не попытался представить интерфейс на уровне сервиса.

Изначально я издевался только над репозиториями / Daos. Итак, структура класса выглядела так:

    public interface ClientRepo{
    ......
    }

    public class ClientRepoImpl implements ClientRepo{
    ......
    }

Смоделировал возвращенные данные как:

    @MockBean 
    private ClientRepo client;

    ....
    Mockito.when(client.isExistFkUnitId(Mockito.any(UUID.class))).thenReturn(false); 

Пока все было хорошо.

Теперь я представил интерфейс на уровень обслуживания как:

    public interface ClientService{
    ......
    }

    public class ClientServiceImpl implements ClientService{
    ......
    }

И попробовал (Попытка вызвать реальный метод обслуживания) :

    @MockBean 
    private ClientService clientService;

    ....
    Mockito.when(clientService.isExistFkUnitId(Mockito.any())).thenCallRealMethod();

Но все время не получал ничего, кроме нуля .

Есть ли способ сделать вызов реального метода с сохранением интерфейса?

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Я думаю, вы хотите использовать аннотацию @Spy вместо @Mock аннотации в поле, где вы хотите вызвать реальный метод. Однако у меня нет примера, чтобы проверить это. https://javadoc.io/doc/org.mockito/mockito-core/2.21.0/org/mockito/Spy.html

Тогда вы можете сделать doCallRealMethod().when(clientService.isExistFkUnitId(Mockito.any())). Потому что со шпионским объектом вы вызываете doReturn/when вместо when/doReturn. https://javadoc.io/doc/org.mockito/mockito-core/2.21.0/org/mockito/Mockito.html#do_family_methods_stubs

0 голосов
/ 10 июля 2020

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

Как правило, модульные тесты следует писать для целевого класса изолированно. Таким образом, вы всегда «тестируете» метод isExistFkUnitId. Вы можете установить макет для определенных c значений:

Mockito.when(clientService.isExistFkUnitId("valueA").thenReturn("answerA");
Mockito.when(clientService.isExistFkUnitId("valueB").thenReturn("answerB");

В любом случае ... чтобы ответить на ваш фактический вопрос:

Если возможно, вы можете создать экземпляр реализации способом что нужный метод работает и вызываем его через макет:

ClientServiceImpl clientServiceImpl = new ClientServiceImpl(...);
// spaghetti code only for demonstration purposes ;)
Mockito.when(clientService.isExistFkUnitId(Mockito.any())).then(i -> clientServiceImpl.isExistFkUnitId((String) i.getArguments()[0]));

PO C test:

@Test
public void testit() {
    Myclass myclass = new Myclass();
    Myinterface mock = Mockito.mock(Myinterface.class);
    Mockito.when(mock.myMethod(Mockito.any())).then(i -> myclass.myMethod((String) i.getArguments()[0]));

    assertThat(mock.myMethod(" works")).isEqualTo("yeehaa works");
}

public interface Myinterface {
    String myMethod(String params);
}

public static class Myclass implements Myinterface {
    @Override
    public String myMethod(String params) {
        return "yeehaa" + params;
    }
}

Не совсем красивое решение, но если выхода нет это должно работать.

...