Задать вопрос

Разработка через тестирование — как не нарушить инкапсуляцию?

Хочу попробовать перейти к разработке через тестирование, и у меня возник ряд вопросов.

Самый основной вопрос - это как соблюдать инкапсуляцию данных и тесты?

Ну, например, если я пишу какого-то бота, который бегает по сайту и считает кол-во тегов на странице. У бота есть конструктор и парочку методов. Ну, например, методы мне не нужно использовать во внешней среде, и я делаю их приватными. Например у меня есть приватный метод, который собирает полный url адрес (например, он должен отсечь якоря, javascript:, из /test сделать site.ru/test и др.), мне нужно его протестировать, но так как он приватный, я не могу этого сделать.

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

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

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

Так что же делать?
  • Вопрос задан
  • 2498 просмотров
Подписаться 4 Оценить Комментировать
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Ну по хорошему мы не должны покрывать тестами приватные методы, только публичные интерфейсы. Но если очень хочется, то любой приватный метод можно сделать публичным в тестах:
public function invokeMethod(&$object, $methodName, array $parameters = array())
{
    $reflection = new \ReflectionClass(get_class($object));
    $method = $reflection->getMethod($methodName);
    $method->setAccessible(true);

    return $method->invokeArgs($object, $parameters);
}


Тема по поводу того хорошо это или плохо частенько обсуждается, иногда по другому никак.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽