Верх страницы
Обложка к записи Подмена защищенных и приватных свойств для тестирования
Время для прочтения: 1 мин. 15 сек.

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

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

Когда данный трюк может пригодится?

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

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

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 );
	}

}

Обновление защищенных и приватных свойств

Для замены защищенного/приватного свойства нам понадобится все тот же ReflectionProperty. Создадим метод update_inaccessible_property:

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 );
}

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

  • С помощью 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;
	}

	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_update_private_property() {
		$suit = new Suit();
		$this->update_inaccessible_property( $suit, 'private_property', 'new private property value' );
		$property = $this->read_inaccessible_property( $suit, 'private_property' );

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

}

Источник: WP Punk.

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Предыдущая запись

Давайте дружить
в Телеграме

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы