Inconsistent behavior with `class_string` of mocks for intersection types
oliverklee opened this issue · 1 comments
oliverklee commented
I have not been able to create a working example for this on the PHPStan playground as this bug involves PHPUnit and the phpstan-phpunit package.
We have a class with a generator function that looks like this:
/**
* Creates an instance of a class taking into account the class-extensions
* API of TYPO3. USE THIS method instead of the PHP "new" keyword.
* Eg. "$obj = new myclass;" should be "$obj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("myclass")" instead!
*
* You can also pass arguments for a constructor:
* \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\myClass::class, $arg1, $arg2, ..., $argN)
*
* @template T of object
* @param class-string<T> $className name of the class to instantiate, must not be empty and not start with a backslash
* @param array<int, mixed> $constructorArguments Arguments for the constructor
* @return T the created instance
*/
public static function makeInstance($className, ...$constructorArguments)
{…}
One of the tests for this method looks like this:
/**
* @test
*/
public function makeInstanceReturnsClassInstance(): void
{
$className = get_class($this->getMockBuilder('foo')->getMock());
self::assertInstanceOf($className, GeneralUtility::makeInstance($className));
}
PHPStan (or phpstan-phpunit) now seems to mix up two different representations of a class string for a intersection types (which both look plausible to me, but they're not the same to PHPStan):
3123 Parameter #1 $className of static method TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance() expects
class-string<foo&PHPUnit\Framework\MockObject\MockObject>,
class-string<foo>&class-string<PHPUnit\Framework\MockObject\MockObject> given.
oliverklee commented
Possibly related: phpstan/phpstan#7200