/** * This test loops through the DataProvider (which provides a list of public * methods from ReflectionClass), ensures the method exists in ReflectionObject * and that when the method is called on ReflectionObject, the method of the * same name on ReflectionClass is also called. * * @param string $methodName * @dataProvider reflectionClassMethodProvider */ public function testReflectionObjectOverridesAllMethodsInReflectionClass($methodName) { // First, ensure the expected method even exists $publicObjectMethods = get_class_methods(ReflectionObject::class); $this->assertContains($methodName, $publicObjectMethods); // Create a mock that will be used to assert that the named method will // be called when we call the same method on ReflectionObject $mockReflectionClass = $this->getMockBuilder(ReflectionClass::class)->disableOriginalConstructor()->setMethods([$methodName])->getMock(); $mockReflectionClass->expects($this->atLeastOnce())->method($methodName); // Force inject node and locatedSource properties on our ReflectionClass // mock so that methods will not fail when they are accessed $mockReflectionClassReflection = new \ReflectionClass(ReflectionClass::class); $php = '<?php class stdClass {}'; $mockReflectionClassNodeReflection = $mockReflectionClassReflection->getProperty('locatedSource'); $mockReflectionClassNodeReflection->setAccessible(true); $mockReflectionClassNodeReflection->setValue($mockReflectionClass, new EvaledLocatedSource($php)); $mockReflectionClassNodeReflection = $mockReflectionClassReflection->getProperty('node'); $mockReflectionClassNodeReflection->setAccessible(true); $mockReflectionClassNodeReflection->setValue($mockReflectionClass, $this->getPhpParser()->parse($php)[0]); // Create the ReflectionObject from a dummy class $reflectionObject = ReflectionObject::createFromInstance(new \stdClass()); // Override the reflectionClass property on the ReflectionObject to use // the mocked reflectionclass above $reflectionObjectReflection = new \ReflectionObject($reflectionObject); $reflectionObjectReflectionClassPropertyReflection = $reflectionObjectReflection->getProperty('reflectionClass'); $reflectionObjectReflectionClassPropertyReflection->setAccessible(true); $reflectionObjectReflectionClassPropertyReflection->setValue($reflectionObject, $mockReflectionClass); // Finally, call the method name with some dummy parameters. This should // ensure that the method of the same name gets called on the // $mockReflectionClass mock (as we expect $methodName to be called) $reflectionObject->{$methodName}('foo', 'bar', 'baz'); }
/** * {@inheritDoc} */ public function getProperty($name) { return new ReflectionProperty($this->betterReflectionObject->getProperty($name)); }