DeprecationHelper: Support mocking and dynamic properties

DeprecationHelper currently breaks dynamic properties
on phpunit mocks. This happens because phpunit starts
mocking the magic methods if they're explicitly defined.

By default, magic methods and up doing nothing, but
if proxying to original methods is enabled, magic methods
are called like regular methods, regarless of whether
property exists or not. With this patch we can workaround
this issue, and create mocks for classes with deprecations.

Needed-By: I4297aea3489bb66c98c664da2332584c27793bfa
Change-Id: Id60a7751ece05669eced6eddd3216da7149411c7
This commit is contained in:
Petr Pchelko 2021-08-04 11:45:27 -07:00
parent 81dd7da45f
commit ac629eed2d
2 changed files with 14 additions and 0 deletions

View file

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

View file

@ -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
*/