или иначе: “Как вызвать приватный метод в другом классе?“

(звезда) этот вопрос с подвохом, т.к. ответ на него должен быть — “никак, без рефакторинга (переписания архитектуры класса, заменой private метода на protected/public)”

Но вот лайфхак: можно, с помощью рефлексии (1):

Вызов защищенных и приватных методов

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

Лучше всего тестировать приватные свойства и методы через публичные методы. Использование данного трюка оправдано в случае экономии времени и при полном понимании зачем вы это делаете.

Пример тестируемого класса:

class Duck {

  private function idea( string $target ) {
    return 'I want to do ' . $target;
  }
 
}

Чтобы прочитать свойство $private_property на другое, нам поможет ReflectionMethod. Создаем метод run_inaccesible_method:

private function run_inaccesible_method( $object, string $method_name, array $args = [] ) 
{
  $method = new ReflectionMethod( $object, $method_name );
  $method->setAccessible( true );
  $result = $method->invokeArgs( $object, $args );
  $method->setAccessible( false );
 
  return $result;
}

Разберем работу метода построчно:

  • С помощью ReflectionMethod получаем в виде объекта метод idea объекта класса Duck;

  • Делаем метод доступным для вызова;

  • Вызываем метод run_inaccesible_method объекта класса Duck с помощью метода invokeArgs;

  • Делаем метод недоступным для вызова;

  • И возвращаем результат.

Пример теста полностью:

use PHPUnitFrameworkTestCase;
 
class Test_Duck extends TestCase 
{

  private function run_inaccesible_method( $object, string $method_name, array $args = [] ) 
  {
    $method = new ReflectionMethod( $object, $method_name );
    $method->setAccessible( true );
    $result = $method->invokeArgs( $object, $args );
    $method->setAccessible( false );
 
    return $result;
  }
 
  public function test_private_method() 
  {
    $duck = new Duck();
    $this->assertSame(
      'I want to do quack-quack',
      $this->run_inaccesible_method( $duck, 'idea', [ 'quack-quack' ] )
    );
  }
}

Источники:

(1) Кобзарев (блог): Вызов защищенных и приватных методов : https://www.kobzarev.com/programming/call-protected-private-methods/

Tags

Нет комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.