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

Methods with "static" return type (introduced in PHP 8) are not handled correctly by test double code generator #4480

Closed
davidbyoung opened this issue Oct 5, 2020 · 2 comments
Assignees
Labels
feature/test-doubles Stubs and Mock Objects type/bug Something is broken

Comments

@davidbyoung
Copy link
Sponsor

Q A
PHPUnit version 9.4.0
PHP version 8.0.0rc1
Installation Method Composer

Summary

The static return type isn't fully supported in mocks in PHP 8.0.

Current behavior

I get the following error when running a test:

Method getInstance may not return value of type Mock_IFoo_54e9358a, its return declaration is "static"

How to reproduce

interface IFoo
{
    public function getInstance(): static;
}

class FooTest extends TestCase
{
    public function testFoo(): void
    {
        $mockFoo = $this->createMock(Foo::class);
        $mockFoo->method('getInstance')
            ->willReturn($mockFoo);
        $this->assertSame($mockFoo, $mockFoo->getInstance());
    }
}

Expected behavior

The above test should pass.

Additional notes

On a related note, although I cannot create a simple repro for the following error, here's a link to the broken unit test and output for a possibly-related issue with supporting static return types. When dumping the eval'd code here, I noticed that some of my tests are resulting in code like the following being generated:

class static
{
}

class Mock_static_5832468d extends static implements PHPUnit\Framework\MockObject\MockObject
{
    use \PHPUnit\Framework\MockObject\Api;
    use \PHPUnit\Framework\MockObject\Method;
    use \PHPUnit\Framework\MockObject\MockedCloneMethod;
}

It looks like static is being treated like the actual name of a return type rather than a special type.

@sebastianbergmann
Copy link
Owner

Here is a corrected and cleaned up version of the example:

<?php
use PHPUnit\Framework\TestCase;

interface Foo
{
    public function getInstance(): static;
}

class FooTest extends TestCase
{
    public function testFoo(): void
    {
        $foo = $this->createMock(Foo::class);

        $foo->method('getInstance')
            ->willReturn($foo);

        $this->assertSame($foo, $foo->getInstance());
    }
}

I am happy to report that I am already able to run it:

PHPUnit 9.4.0-1-g7646ea0ce by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.024, Memory: 6.00 MB

OK (1 test, 1 assertion)

I hope to have these changes ready for commit/push soon.

@sebastianbergmann sebastianbergmann added type/enhancement A new idea that should be implemented type/bug Something is broken and removed type/bug Something is broken type/enhancement A new idea that should be implemented labels Oct 6, 2020
@sebastianbergmann sebastianbergmann changed the title Mocked methods with static return types are not supported Methods with "static" return type (introduced in PHP 8) are not handled correctly by test double code generator Oct 6, 2020
@sebastianbergmann
Copy link
Owner

This requires the fix for PHP bug 80190.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature/test-doubles Stubs and Mock Objects type/bug Something is broken
Projects
None yet
Development

No branches or pull requests

2 participants