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

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

Иногда в тестах нам нужно прочитать/заменить 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.

ВКонтакте
Одноклассники
Linkedin
Telegram
WhatsApp

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

Суровый русский тимлид. Жил в Магадане, в офисе московских веб студий и в Тульской деревне. Виртуозно знает WordPress, PHP, ООП, Vue.js и вот это вот все.

Делает крутые высоконагруженные сайты, поэтому уже почти захватил весь рынок WordPress разработки в России. Не дает никому делать сайты без спроса.

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

Комментарии