Рецепты для тестирования

Чтение защищенных и приватных свойств

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

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

class Suit {

	private $private_property = 'private property value';

}

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

private function read_inaccessible_property( $object, string $property_name ) {
	$property = new ReflectionProperty( $object, $property_name );
	$property->setAccessible( true );
	$value = $property->getValue( $object );
	$property->setAccessible( false );

	return $value;
}

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

  • С помощью ReflectionProperty получаем в виде объекта свойство private_property объекта класса Suit;
  • Делаем свойство доступным для редактирования;
  • Читаем свойство private_property объекта класса Suit;
  • Делаем свойство недоступным для редактирования;
  • И возвращаем результат.

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

use PHPUnit\Framework\TestCase;
use ReflectionProperty;

class Test_Suit extends \PHPUnit\Framework\TestCase {

	private function read_inaccessible_property( $object, string $property_name ) {
		$property = new ReflectionProperty( $object, $property_name );
		$property->setAccessible( true );
		$value = $property->getValue( $object );
		$property->setAccessible( false );

		return $value;
	}

	public function test_read_property() {
		$suit     = new Suit();
		$property = $this->read_inaccessible_property( $suit, 'private_property' );

		$this->assertSame( 'private property value', $property );
	}

}