diff --git a/includes/debug/DeprecationHelper.php b/includes/debug/DeprecationHelper.php index 2e78535eac4..919dd2c5960 100644 --- a/includes/debug/DeprecationHelper.php +++ b/includes/debug/DeprecationHelper.php @@ -198,6 +198,12 @@ trait DeprecationHelper { if ( $ownerClass ) { // Someone tried to access a normal non-public property. Try to behave like PHP would. trigger_error( "Cannot access non-public property $qualifiedName", E_USER_ERROR ); + } elseif ( property_exists( $this, $name ) ) { + // Normally __get method will not be even called if the property exists, + // but in tests if we mock an object that uses DeprecationHelper, + // __get and __set magic methods will be mocked as well, and called + // regardless of the property existence. Support that use-case. + return $this->$name; } else { // Non-existing property. Try to behave like PHP would. trigger_error( "Undefined property: $qualifiedName", E_USER_NOTICE ); diff --git a/tests/phpunit/includes/debug/DeprecationHelperTest.php b/tests/phpunit/includes/debug/DeprecationHelperTest.php index b438247610f..565b04aa242 100644 --- a/tests/phpunit/includes/debug/DeprecationHelperTest.php +++ b/tests/phpunit/includes/debug/DeprecationHelperTest.php @@ -78,6 +78,14 @@ class DeprecationHelperTest extends MediaWikiIntegrationTestCase { } ); } + public function testDynamicPropertyOnMockObject() { + $testObject = $this->getMockBuilder( TestDeprecatedClass::class ) + ->enableProxyingToOriginalMethods() + ->getMock(); + $testObject->blabla = 'test'; + $this->assertSame( 'test', $testObject->blabla ); + } + /** * @dataProvider provideSet */