Mockito - как высмеивать и выражать ожидания в отношении абстрактного метода класса (т.е. обратного вызова) - PullRequest
0 голосов
/ 25 ноября 2018

Я пытаюсь провести юнит-тестирование абстрактного класса, поэтому мне нужно предоставить имитационную реализацию абстрактных методов класса.

Я думаю, что я нахожусь в нишевой ситуации (!), Поскольку ни @Mock или @Spy, кажется, помогают.

  • пробовал Mockito.mock(SimpleClient.class, Mockito.CALLS_REAL_METHODS), но это полностью разрушает мой абстрактный класс (создает его без вызова конструктора и запуска в NPE)
  • пытался @Spy но для этого требуется либо экземпляр реального класса (который я не могу предоставить, поскольку он абстрактный duh), либо он попытается вызвать конструктор без аргументов, который не существует.

(Контекст, хотя вам это не нужно: класс является клиентом обмена сообщениями, например, имеет методы sendMessage() и abstract onMessage(), и, очевидно, мне нужно использовать реальную реализацию sendMessage() и смоделировать обратный вызов abstract onMessage())

1 Ответ

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

Я нашел следующее

  • , чтобы пойти первым подходом (Mockito.mock), они добавили возможность правильно построить базовый реальный объект, используяпроизвольный конструктор (и, надеюсь, после этого Moquito «заглушит» каждый метод, когда вы выражаете свои ожидания, как показано ниже):

    MyClass mock = Mockito.mock(MyClass.class, Mockito.withSettings()
    .useConstructor("stringArg", 17)
    .defaultAnswer(Mockito.CALLS_REAL_METHODS));
    
    // ...
    
    Mockito.when(mock.onMyAbstractMethod(Mockito.anyInt())).then(
    invocation -> mock.callAnotherRealMethodOnTheMock(invocation.getArgument(0)));
    
  • , чтобы перейти на второй подход@Spy нужен созданный экземпляр класса, поэтому в этом случае вам действительно нужно сначала создать его подкласс.

Дополнительное примечание : отдельная проблема, уродливаяКроме того, это происходит, если, скажем, onMyAbstractMethod возвращает void, в этом случае синтаксис Mockito.when... не работает из-за языкового ограничения, что, по-видимому, плохо документировано.Нужно сделать это наоборот и сказать:

        Mockito.doAnswer(invocation -> mock.callAnotherRealMethodOnTheMock(invocation.getArgument(0)))
        .when(mock).onMyAbstractMethod(1);
...