Skip to content

PHPUnit exposes an internal API to the userland #4309

@morozov

Description

@morozov
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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions