phony icon indicating copy to clipboard operation
phony copied to clipboard

Cannot provide ad-hoc implementation of static function that returns self type.

Open jmalloc opened this issue 2 years ago • 0 comments

Given:

abstract class C {
    abstract static function fun(): self;
}

Phony::partialMock(
    [
        C::class,
        [
            'static fun' => function () {
                return new C();
            },
        ]
    ]
);

The following fatal error occurs:

Fatal error: Declaration of PhonyMock_C_8::fun() must be compatible with C::fun(): C in vendor/eloquent/phony/src/Mock/MockFactory.php(91) : eval()'d code on line 5

This makes some sense, as that closure is obviously not returning the self type, however adding the self type doesn't/can't work in this scenario either, as in most cases it would refer to the type of the surrounding class (such as a PHPUnit test suite implementation, for example).

FWIW, this is the error given when naively adding :self to the closure:

Call to undefined method ReflectionFunction::getDeclaringClass()

Which I assume is simply because it's a closure, it does not have a declaring class (ReflectionFunction, not ReflectionMethod).

As a workaround I've implemented this static function by hand-rolling a class in my test suite, but this had a number of undesirable knock-on effects, including preventing verifications using onStatic() from working for this function.

My PHP is pretty rusty at this point so I'm having trouble coming up with any good solutions, but figured I may as well document this issue before I forget the details.

jmalloc avatar Mar 06 '22 02:03 jmalloc