Skip to content

Method with a class argument and default value can't be mocked #568

@bicpi

Description

@bicpi

Hi,
since 8.1, PHP supports the usage of the new operator in initializers (https://php.watch/rfcs/new_in_initializers).

Given this dummy class:

class DummyClass {}

And an interface with a method using a DummyClass instance as default argument of a method:

interface BarService
{
    public function doIt(DummyClass $myClass = new DummyClass()): void;
}

And a service using the interface as a dependency:

class FooService
{
    public function __construct(
        private readonly BarService $bar
    ) {
    }

    public function execute(): void
    {
        $this->bar->doIt();
    }
}

The following test fails with a fatal PHP error in the phpspec/prophecy code:

namespace Tests;

use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;

class DummyClass {...}
interface BarService {...}
class FooService {...}

class FooServiceTest extends TestCase
{
    use ProphecyTrait;

    /**
     * @test
     */
    public function it_fails(): void
    {
        $someService = $this->prophesize(BarService::class);
        $someService
            ->doIt()
            ->shouldBeCalled();

        $fooService = new FooService($someService->reveal());
        $fooService->execute();
    }
}

The error message is:

PHP Fatal error:  Constant expression contains invalid operations in /vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php(49) : eval()'d code on line 5

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions