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

джамшут

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

выводы:
1. тестировать нужно все интерфейсы, а не только "публичные".
2. функции тоже нужно тестировать, ибо они представляют из себя интерфейс вызова исполняемого кода.
 

zerkms

TDD infected
Команда форума
джамшут
смотря что подразумевать под "тестировать". если следовать парадигме TDD, то тестировать приватные методы не нужно
это следует как из самой парадигмы, так и из трудов разных умных людей
 

zerkms

TDD infected
Команда форума
korchasa
пхп4 умер уже, не надо уже извращаться :)

-~{}~ 17.03.08 18:20:

ps: чувствую ещё немного, и в этом треде наследование предложат заменить копипастом исходного класса с дописыванием новых методов
 

korchasa

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

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

джамшут

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

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
а если немного напрячь прямую извилину, то можно, например, заметить отсутствие принципиальной разницы между "написать тесткейс", "написать техническое задание" и "написать доку к функции". разница лишь в том, что первое - полностью автоматизировано, второе - проверяется тестерами, а третее - возлагается на наблюдательность и прозорливость программиста.
Насколько я понимаю, TDD подразумевает модульное тестирование, а ты говоришь о приемочных тестах
 

джамшут

Новичок
какая разница между приёмом приложения, приёмом модуля, приёмом класса и приёмом одной функции?
 

джамшут

Новичок
если тебе кажется, что написание хорошего калькулятора - это легко, то ты глубоко заблуждаешься.
 

Zh0rzh

Новичок
Подниму тему.

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

http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
 

whirlwind

TDD infected, paranoid
Мое мнение: TTD vs OOP
Они всегда в противостоянии. Нарушение инкапсуляции (unfinalize, partial mocks) чревато снижением чувствительности тестов. Единственное допущение - легаси код. А в нем приватные методы тестировать не имеет смысла.
 

fixxxer

К.О.
Партнер клуба
Ниасилил многа букф. Но все же, а почему бы просто не наследоваться от тестируемого и не переопределять __call ?
 

Zh0rzh

Новичок
Вкратце.
Для получения доступа к приватным переменным достаточно использовать 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)
        );
    }
}
?>
 

phprus

Moderator
Команда форума
Ухты! Это-же Паблик Морозов во всей своей красе.
Даже и не знал, что в PHP есть "легальная" конструкция для вызова закрытых методов класса.
 

fixxxer

К.О.
Партнер клуба
>> дык все просто - __call когда срабатывает?

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

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