Если вам понадобился данный трюк то скорее всего вы имеете проблему в архитектуре вашего класса/приложения. Его использование это крайняя мера. Лучше всего тестировать приватные свойства и методы через публичные методы. Использование данного трюка оправдано в случае экономии времени и при полном понимании зачем вы это делаете.
Пример тестируемого класса:
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' ] )
);
}
}