Могу ли я смоделировать вызов метода защищенного суперкласса в Java? - PullRequest
1 голос
/ 03 октября 2011

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

например. :

public class A extends B {
    @Override
    protected int calculate(int x, int y) {
         int result = super.calculate(x, y);
         result += 10;
         return result;
    } 
}

Так можно ли издеваться над super.calcluate(x,y)? Я попробовал это с шпионом, но шпион не смог вызвать супер метод, потому что я думаю, что он выходит за рамки возможного.

Ответы [ 4 ]

3 голосов
/ 03 октября 2011

Когда вы издеваетесь над объектом, вы не заботитесь о его реализации. Вы только добавляете ожидания относительно того, какой метод вызывается.

Если вы дразните A, то ваши ожидания скажут что-то: «Я ожидаю, что метод вычисления для A будет вызван с параметрами 2 и 3, и результат будет 15».

Вам все равно, что метод вычисления делает на практике, вот в чем суть насмешки.

3 голосов
/ 03 октября 2011

Я думаю, что фреймворк позволит вам насмехаться над protected участниками, но если ваш фальшивый фреймворк не делает, вы задумывались о создании заглушки класса?

public class AStub extends A {
    @Override
    protected int calculate(int x, int y) {
        // do stub calculation 
        return calculation;
    }
}
2 голосов
/ 03 октября 2011

Вы не должны издеваться над вызовом супер.Модульное тестирование предназначено для проверки функциональности класса, и функциональность классов-предков является частью этой функциональности .

Единственный случай, когда вам нужно издеваться над суперклассом, это когда класс-предок ведет себя плохо - например, инициализация внешних классов как часть его собственной инициализации (без проекции внедрения зависимости) или доступ к внешним ресурсам (безпроекция внедрения зависимости).Если у вас есть доступ к классу предков, выполните рефакторинг, чтобы устранить эти проблемы.

1 голос
/ 03 октября 2011

К сожалению, я не думаю, что есть простой способ высмеять super.calculate.

Я вижу, что вы хотите написать «чистый» модульный тест для A, который не опирается на B, что является разумной целью. Но если A вызывает защищенный метод в своем суперклассе, Java затрудняет разделение двух классов.

Это один из многих примеров, когда использование классов наследования пар более тесно, чем вы хотели бы.

В идеале A будет оборачивать B, а не расширять его (т. Е. Используя композицию, а не наследование), и тогда будет вызывать myB.calculate вместо super.calculate.

Оба класса могут реализовывать один и тот же интерфейс (например, вычисляемый), чтобы клиенты могли полиморфно обрабатывать их. Этот подход потребовал бы, чтобы B.calculate был публичным или, по крайней мере, публичным. Ваш модульный тест может настроить A, который оборачивает макет B, тем самым решая вашу проблему.

Я думаю, что вам нужно выбрать между увеличением видимости Calculate (), как описано выше, и написанием чистого модульного теста - я не думаю, что вы можете иметь оба.

...