Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method with an enum argument and default value can't be mocked #567

Closed
bicpi opened this issue Sep 17, 2022 · 6 comments · Fixed by #618
Closed

Method with an enum argument and default value can't be mocked #567

bicpi opened this issue Sep 17, 2022 · 6 comments · Fixed by #618
Labels

Comments

@bicpi
Copy link

bicpi commented Sep 17, 2022

Hi,
given this enum (PHP 8.1+):

enum AppType
{
    case IOS;
    case ANDROID;
}

And an interface with a method using the enum as default argument of a method:

interface BarService
{
    public function doIt(AppType $appType = AppType::ANDROID): void;
}

And a service using the interface as a dependency:

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

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

The following test fails:

namespace Tests;

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

enum AppType {...}
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:

Error : Class "Double\BarService\Tests\AppType" not found

When passing the default value explicitly works though.

@stof stof added the PHP8.1 label Sep 17, 2022
@stof
Copy link
Member

stof commented Sep 17, 2022

This error has nothing to do with new in initializers (there is no new in your initializers). It is about support for enums in default values of an argument.

@bicpi
Copy link
Author

bicpi commented Sep 17, 2022

True, I think I also observed an issue with new usage, I'll refine the description.

@stof
Copy link
Member

stof commented Sep 17, 2022

If there is also an issue with new (which is likely as we haven't done anything to support it), please open a separate issue for it (as the fix might not be the same).

@bicpi bicpi changed the title Support for "new" in initializers missing? Method with enum argument and default value can't be mocked Sep 17, 2022
@bicpi bicpi changed the title Method with enum argument and default value can't be mocked Default value for enum method argument can't be mocked Sep 18, 2022
@bicpi bicpi changed the title Default value for enum method argument can't be mocked Method with argument of type "enum" and default value can't be mocked Sep 18, 2022
@bicpi bicpi changed the title Method with argument of type "enum" and default value can't be mocked Method with an enum argument and default value can't be mocked Sep 18, 2022
@bicpi
Copy link
Author

bicpi commented Sep 18, 2022

I reduced this issue to the problem with the enum argument; after testing the case with the new usage in a method's default value, I created the separate issue #568.

@lyrixx
Copy link
Contributor

lyrixx commented Nov 21, 2022

I confirm the issue.

As soon as a default value is used for an argument typed with a Enum, prophecy crash.

@jdreesen
Copy link
Contributor

I can also confirm this. The problem is, that the generated default value is in the wrong namespace, because the leading \ is missing.

This seems only to be a problem in PHP 8.1, see: https://3v4l.org/3JPCM

I proposed a fix: #618

@stof stof closed this as completed in #618 Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants