Подмена защищенных и приватных свойств для тестирования

Иногда в тестах нам нужно заменить protected или private свойство объекта, чтобы ускорить тест или более качественно протестировать объект.

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

class Suit {

	private $private_property = 'private property';

	public function method(): string {
		return $this->private_property;
	}

}

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

use PHPUnitFrameworkTestCase;
use ReflectionProperty;

class Test_Suit extends PHPUnitFrameworkTestCase {

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

	public function test_method() {
		$suit = new Suit();
		$this->assertSame( 'private property', $suit->method() );

		$this->update_inaccessible_property( $suit, 'private_property', 'new private property' );
		$this->assertSame( 'new private property', $suit->method() );
	}

}

Вся магия происходит в методе update_inaccessible_property. Разберем построчно.

Получаем доступ к свойству private_property объекта класса Suit.

$property = new ReflectionProperty( $object, $property_name );

Делаем свойство доступным для редактирования:

$property->setAccessible( true );

Устанавливаем к свойству private_property объекта класса Suit значение new private property:

$property->setValue( $object, $value );

Делаем свойство недоступным для редактирования:

$property->setAccessible( false );

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

%d такие блоггеры, как: