Как проверить вызов класса super.method() родительского класса?

У меня есть три очень простых класса. Один из них расширяет родительский класс.

public class Parent{
    protected String print() {
        // some code
    }
}

Вот дочерний класс.

public class Child extends Parent {
    /**
     * Shouldn't invoke protected Parent.print() of parent class.
     */
    @Override
    protected String print() {
        // some additional behavior
        return super.print();
    }
}

И тестовый класс.

public class ChildTest {

    @Test
    public void should_mock_invocation_of_protected_method_of_parent_class() throws Exception {

        // Given
        Child child = PowerMockito.mock(Child.class);
        Method method = PowerMockito.method(Parent.class, "print");
        PowerMockito.when(child, method).withNoArguments().thenReturn("abc");

        // When
        String retrieved = child.print();

        // Than
        Mockito.verify(child, times(1)).print(); // verification of child method
        Assert.assertEquals(retrieved, "abc");
    }
}

Мне нужно проверить вызов super.print(). Как я могу это сделать?

Ответ 1

Это давний вопрос, но вот как я это сделал, используя шпион Mockito, создав метод, который вызывает родительский метод в дочернем классе:

public class Child extends Parent {
    /**
     * Shouldn't invoke protected Parent.print() of parent class.
     */
    @Override
    protected String print() {
        // some additional behavior
    return callParent();
    }

    protected callParent()
    {
      super.print();
    }

}

И в тесте:

@Test
public void sould_mock_invocation_of_protected_method_of_parent_class() throws Exception {

    // Given
    Child child = Mockito.spy(new Child());
    Mockito.doReturn(null)
           .when(child)
           .callParent();
    // When
    String retrieved = child.print();

    // Then
    Mockito.verify(child, times(1)).callParent(); // verification of child method
    Assert.assertEquals(retrieved, "abc");
}

Примечание: этот тест проверяет только то, что мы вызываем родительский метод в дочернем классе.

Ответ 2

Поскольку вы запрашиваете unit test, я предлагаю вам unit test метод print() класса Parent, а не класс Child.

Далее, поскольку метод print() класса Child не добавляет никакого поведения, он может быть удален:

public class Child extends Parent {
    // inherits print() method from Parent
}

Этот контракт является частью Java Language Specification (JLS) и не нуждается в проверке:

Класс C наследует от своего прямого суперкласса и прямых суперинтерфейсов все абстрактные и не абстрактные методы суперкласса и суперинтерфейсов, которые являются общедоступными, защищенными или объявленными по умолчанию доступом в том же пакете, что и C, и не являются переопределенными (§ 8.4.8.1) и не скрыты (§8.4.8.2) декларацией в классе.

Ответ 3

Если вы вызываете super.print() в методе класса Child <print(), конечно, будет вызвана реализация класса родителя print(). Как проверить, действительно ли это происходит, зависит от того, что действительно делает реализация класса родителя.

P.S. комментарии в вашем коде Shouldn't invoke protected Parent.print() of parent class и Parent.print() method shouldn't be invoked. неверны.

Ответ 4

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

Это не требует проверки. super.someMethod() вызывается в соответствии с спецификацией java language.