Заглушить метод из тестируемого класса, чтобы протестировать другой метод

Я обнаружил, что stub и mock очень полезны при тестировании. Но меня интересует одно. Я думаю, пример покажет это ясно.

Class A {
    public function isOk() {
        // some work
    }

    public function iAmDepend() {
        if ($this->isOk()) {
            // do work
        }
    }
}

class TestA {
    public function testIsOk() {
        // Test itOk here
    }

    public function testIAmDepend() {
        mock(A)->method(isOk)->return(true);
        // tests for iAmDepend
    }

}

Разумно ли делать что-то подобное? Метод-заглушка тестируемого класса. Или, может быть, это нарушает какие-то правила?

PS. Я не могу рефакторить код


person Marcin Rogacki    schedule 18.07.2012    source источник
comment
Под зависимостями в терминологии модульного тестирования обычно понимаются другие классы, от которых зависит класс, а не методы внутри того же класса. В вашем примере вы обычно издеваетесь над обоими методами класса A и предоставляете это как имитируемую зависимость другого класса (например, classB), которую вы будете тестировать с помощью своего модульного теста.   -  person StuartLC    schedule 18.07.2012
comment
Вы описали обычную ситуацию. Но меня интересует необычное. Должен ли я понимать ваше заявление как не одобряющее этот метод тестирования? Может быть, это важно, в PHP я могу выбирать, какие методы я хочу заглушить.   -  person Marcin Rogacki    schedule 18.07.2012


Ответы (1)


Ваши примеры верны, т. е. testIsOk проверяет только IsOk, а testIAmDepend только IAmDepend.

Но между макетом и заглушкой есть важная разница, которую вы должны понимать: разница между макетом и заглушкой.

В вашем примере, если testIAmDepend проверяет, что isOk был вызван с некоторыми аргументами, и это является частью вашего утверждения для модульного теста, это насмешка. В противном случае это заглушка, и вы не сможете проверить, вызывался он или нет.

person Akim    schedule 18.07.2012
comment
Хорошо, так что здесь я заглушаю :) Спасибо за ответ. Мне интересно, согласится ли кто-нибудь с вашим мнением. - person Marcin Rogacki; 18.07.2012
comment
Например, в RhinoMock и других фреймворках .Net есть концепция частичной имитации. Используя его, вы можете создать объект CUT (тестируемый класс), определить заглушки или макеты для некоторых методов, а затем подтвердить поведение CUT в некоторых условиях. Таким образом, вы можете имитировать работу с внешними ресурсами или зависимостями и утверждать только обработку ошибок. Точно как в вашем примере. - person Akim; 18.07.2012
comment
Единственная причина, по которой я вижу, что это действительно так, заключается в том, что в этом случае вы тестируете оба общедоступных метода, и скажем, например, что метод, который вы в настоящее время заглушаете, является закрытым, что это будет иметь некоторый запах кода, поскольку заглушка частного метода является плохая практика. Я учусь этому трудным путем. Также я бы рекомендовал полностью заглушить тестируемый класс. Вы должны иметь возможность проводить модульное тестирование своего класса, не заглушая методы того же класса. - person Elias Perez; 23.02.2017