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

PHPUnit exposes an internal API to the userland #4309

Closed
morozov opened this issue Jun 20, 2020 · 2 comments
Closed

PHPUnit exposes an internal API to the userland #4309

morozov opened this issue Jun 20, 2020 · 2 comments
Labels
feature/test-doubles Stubs and Mock Objects type/bug Something is broken

Comments

@morozov
Copy link
Contributor

morozov commented Jun 20, 2020

Q A
PHPUnit version 9.2.3
PHP version 7.4.7
Installation Method Composer

Summary

In a project that uses PHPUnit and Psalm, Psalm detects the issue in PHPUnit that cannot be fixed in the project and therefore has to be suppressed.

Current behavior

ERROR: InternalMethod - tests/ExampleTest.php:17:12 - The method 
PHPUnit\Framework\MockObject\Builder\InvocationMocker::method has been marked as internal 
(see https://psalm.dev/175)
        )->method('test');

The above is caused by the interface returning a class marked as @internal:

  1. public function expects(InvocationOrder $invocationRule): BuilderInvocationMocker;
  2. /**
    * @internal This class is not covered by the backward compatibility promise for PHPUnit
    */
    final class InvocationMocker implements InvocationStubber, MethodNameMatch

This issue was already brought up in #3742 (comment).

How to reproduce

<?php declare(strict_types=1);

namespace Test;

use PHPUnit\Framework\TestCase;

class ExampleTest extends TestCase
{
    /**
     * @test
     */
    public function testExample() : void
    {
        $t = $this->createMock(T::class);
        $t->expects(
            $this->never()
        )->method('test');
    }
}

interface T
{
    public function test() : void;
}

See the full demo project in the gist:

$ composer install
$ vendor/bin/psalm

Since the project's tests extend and use the PHPUnit test classes, suppressing errors in the vendor/ directory doesn't help.

Expected behavior

PHPUnit doesn't expose the internal parts of its API to the userland.

@ostrolucky
Copy link
Contributor

Ref #3236. Looks like we just need to create PR to remove @internal from this class.

@morozov
Copy link
Contributor Author

morozov commented Jun 21, 2020

@ostrolucky, thanks for the pointer. I thought of adding an interface that extends InvocationStubber and MethodNameMatch. Then, instead of returning an InvocationMocker, the method could return an instance of that interface.

But just removing @internal may be an acceptable short-term solution.

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

3 participants