[TDD] Как покрывать тестами private методы в классе?

1. когда из нескольких методов общий код выносится в отдельный метод, появляется приватный интерфейс. мы не можем изменить параметры вызова вызываемого метода и возвращаемый им результат без переписывания, вызывающих.
2. когда от этого класса отнаследовали другой, но методы этого другого продолжают вызывать методы родителя - появляется "защищённый" интерфейс. мы не можем изменить внутренности родителя без оглядки на потомков.
3. этот пункт пропускаем, ибо пакетов в пхп нет.
4. и только когда мы предоставляем право дёргать метод кому угодно появляется публичный интерфейс. мы не можем менять имена методов, параметры их вызова и возвращаемый ими результат без риска поломать зависимости с другими классами.
5. можно ещё упомянуть про внешние интерфейсы - http, corba, soap, xmlrpc...

выводы:
1. тестировать нужно все интерфейсы, а не только "публичные".
2. функции тоже нужно тестировать, ибо они представляют из себя интерфейс вызова исполняемого кода.
 
джамшут
смотря что подразумевать под "тестировать". если следовать парадигме TDD, то тестировать приватные методы не нужно
это следует как из самой парадигмы, так и из трудов разных умных людей
 
korchasa
пхп4 умер уже, не надо уже извращаться :-)

-~{}~ 17.03.08 18:20:

ps: чувствую ещё немного, и в этом треде наследование предложат заменить копипастом исходного класса с дописыванием новых методов
 
Автор оригинала: zerkms
korchasa
пхп4 умер уже, не надо уже извращаться :-)
Ну я не предлагаю так делать. Просто было интересно какие будут аргументы.

ps: чувствую ещё немного, и в этом треде наследование предложат заменить копипастом исходного класса с дописыванием новых методов
Ну эту тему можно рядом завести. Что-нибудь типа "прегенераторы кода vs абстракции, или когда наступает good enough" ;)
 
а если немного напрячь прямую извилину, то можно, например, заметить отсутствие принципиальной разницы между "написать тесткейс", "написать техническое задание" и "написать доку к функции". разница лишь в том, что первое - полностью автоматизировано, второе - проверяется тестерами, а третее - возлагается на наблюдательность и прозорливость программиста.
 
а если немного напрячь прямую извилину, то можно, например, заметить отсутствие принципиальной разницы между "написать тесткейс", "написать техническое задание" и "написать доку к функции". разница лишь в том, что первое - полностью автоматизировано, второе - проверяется тестерами, а третее - возлагается на наблюдательность и прозорливость программиста.
Насколько я понимаю, TDD подразумевает модульное тестирование, а ты говоришь о приемочных тестах
 
какая разница между приёмом приложения, приёмом модуля, приёмом класса и приёмом одной функции?
 
если тебе кажется, что написание хорошего калькулятора - это легко, то ты глубоко заблуждаешься.
 
Подниму тему.

Себастьян Бергман сегодня написал, как сейчас в PHPUnit можно проверять приватные свойства и методы

http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
 
Мое мнение: TTD vs OOP
Они всегда в противостоянии. Нарушение инкапсуляции (unfinalize, partial mocks) чревато снижением чувствительности тестов. Единственное допущение - легаси код. А в нем приватные методы тестировать не имеет смысла.
 
Ниасилил многа букф. Но все же, а почему бы просто не наследоваться от тестируемого и не переопределять __call ?
 
Вкратце.
Для получения доступа к приватным переменным достаточно использовать assertAttributeEquals
PHP:
<?php
class FooTest extends PHPUnit_Framework_TestCase
{
    public function testPrivateAttribute()
    {
        $this->assertAttributeEquals(
          'baz',  /* expected value */
          'bar',  /* attribute name */
          new Foo /* object         */
        );
    }
}
?>

А для доступа к приватным методам в PHP 5.3.2 появилась возможность вызывать такие методы через Reflection

PHP:
<?php
class FooTest extends PHPUnit_Framework_TestCase
{
    /**
     * @covers Foo::doSomethingPrivate
     */
    public function testPrivateMethod()
    {
        $method = new ReflectionMethod(
          'Foo', 'doSomethingPrivate'
        );
 
        $method->setAccessible(TRUE);
 
        $this->assertEquals(
          'blah', $method->invoke(new Foo)
        );
    }
}
?>
 
Ухты! Это-же Паблик Морозов во всей своей красе.
Даже и не знал, что в PHP есть "легальная" конструкция для вызова закрытых методов класса.
 
>> дык все просто - __call когда срабатывает?

ну... если я извне вызову защищенный метод, то есть "протестирую" его напрямую, __call сработает. а ты хочешь тестировать факт того, что публичный метод вызвал определенный защищенный? ох. по моему проще что-то другое придумать =)

с Reflection - круто, теперь можно извращаться как в джаве =)
 
Сверху