Иногда в тестах нам нужно заменить 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 );