phpspec / prophecy

Highly opinionated mocking framework for PHP 5.3+
MIT License
8.53k stars 241 forks source link

Prophecy not work with virtual private __method #450

Open BruceGitHub opened 4 years ago

BruceGitHub commented 4 years ago

I love prophecy I use this library a lot. I have seen strange behavior when trying to mock method like this __methodName so I looked in code base and I found that exist a whitelist of reflectable methods. I would mock these methods like __doRequest from soap ext-library for example with __ in the name. If this behavior can be changed, it would be a great thing, if you agree I could make a PR.

Example

class Test {
   void function __test() {
   }
}
$test = $this->prophesize(Test::class);
$test->__test()->shouldBeCalled();

$testReveal = $test->reveal();
$testReveal->__test();

Output

Double\Test\P1:              
   ├ No calls have been made that match:                    
   ├     Double\Test\P1->__test()
   ├   but expected at least one.                           

Class in prophecy that contains a whitelist

class ClassMirror
{
    public static $reflectableMethods = array(
        '__construct',
        '__destruct',
        '__sleep',
        '__wakeup',
        '__toString',
        '__call',
        '__invoke',
    );
...
    private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node)
    {
      ...
            foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
            if (0 === strpos($method->getName(), '_')
                && !in_array($method->getName(), self::$reflectableMethods)) {
                continue;
            }
      ...
    }