英文:
PHP Unit Class "PHPUnit\Metadata\Api\DataProvider" not found [with repro case]
问题
我已经通过Composer安装了PHPUnit,并编写了一个简单的单元测试文件(实际上是来自PHPUnit示例的)。
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class CheckFreeSeatsTest extends TestCase
{
public function testCanBeCreatedFromValidEmail(): void
{
$this->assertSame("foo", "foo");
}
}
每次我执行测试文件时,都会出现以下错误:
PHPUnit内部发生了一个错误。
消息:未找到类“PHPUnit\Metadata\Api\DataProvider”
位置:C:\www\vendor\phpunit\phpunit\src\Framework\TestBuilder.php:38
我已经执行了composer update
、composer dumpautoload --dev
,并传递了--bootstrap=vendor/autoload.php
等命令。
出现这个问题的原因是autoload.php
(确切地说是autoload_static.php
)缺少PHPUnit\Metadata\Api\DataProvider
的映射(甚至更多的映射)。
是否有人可以检查他的autoload
文件中是否包含"DataProvider.php"?
例如,以下是任何autoload_*.php
文件中找到的唯一Metadata包含部分:
'PHPUnit\\Metadata\\UsesFunction' => __DIR__ . '/../phpunit/phpunit/src/Metadata/UsesFunction.php',
'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => __DIR__ . '/../phpunit/phpunit/src/Metadata/Version/ComparisonRequirement.php',
'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => __DIR__ . '/../phpunit/phpunit/src/Metadata/Version/ConstraintRequirement.php',
'PHPUnit\\Metadata\\Version\\Requirement' => __DIR__ . '/../phpunit/phpunit/src/Metadata/Version/Requirement.php',
更多信息:我自己不使用DataProvider,但TestBuilder.php正在创建一个,但它依赖于似乎没有创建的autoload数据。
对此有什么提示将会很有帮助。
复现案例
以下是一个在Docker Linux容器设置中完全复制此问题的Windows PowerShell复现案例。只需将其放入一个空目录并执行它。
Set-StrictMode -Version 3
$outDir = "$PSScriptRoot/out_dir"
if(Test-Path $outDir)
{
Remove-Item -Force -Recurse $outDir | Out-Null
}
New-Item -ItemType Directory $outDir | Out-Null
@'
{
"name": "root/app",
"require-dev": {
"phpunit/phpunit": "^10"
}
}
'@ | Out-File $outDir\composer.json -Encoding ascii
docker run --volume "$($outDir):/app" --rm -it composer/composer composer update
@'
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class EmailTest extends TestCase
{
public function testCanBeCreatedFromValidEmail(): void
{
$this->assertSame("foo", "foo");
}
}
'@ | Out-File $outDir\EmailTest.php -Encoding ascii
docker run --volume "$($outDir):/app" --rm -it composer/composer ./vendor/bin/phpunit EmailTest.php
希望对你有所帮助。
英文:
I've installed php unit via composer and have written a simple unit test file (it is actually from phpunit's example)
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class CheckFreeSeatsTest extends TestCase
{
public function testCanBeCreatedFromValidEmail(): void
{
$this->assertSame("foo", "foo");
}
}
Nothing to write home about
Each time I execute the test file I get a
An error occurred inside PHPUnit.
Message: Class "PHPUnit\Metadata\Api\DataProvider" not found
Location: C:\www\vendor\phpunit\phpunit\src\Framework\TestBuilder.php:38
#0 C:\www\vendor\phpunit\phpunit\src\Framework\TestSuite.php(477): PHPUnit\Framework\TestBuilder->build(Object(ReflectionClass), 'testCanBeCreate...')
I've already executed composer update
, composer dumpautoload --dev
, passing --bootstrap=vendor/autoload.php
etc.
For whatever reason, the autoload.php (autoload_static.php
to be precisely) is missing a mapping for PHPUnit\Metadata\Api\DataProvider
(or even more of those)
Can somebody check, whether his or her autoload files contain "DataProvider.php" ?
For instance these are the only Metadata includes found in any autoload_*.php files
'PHPUnit\\Metadata\\UsesFunction' => __DIR__ . '/..' . '/phpunit/phpunit/src/Metadata/UsesFunction.php',
'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => __DIR__ . '/..' . '/phpunit/phpunit/src/Metadata/Version/ComparisonRequirement.php',
'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => __DIR__ . '/..' . '/phpunit/phpunit/src/Metadata/Version/ConstraintRequirement.php',
'PHPUnit\\Metadata\\Version\\Requirement' => __DIR__ . '/..' . '/phpunit/phpunit/src/Metadata/Version/Requirement.php',
More info: I do not use DataProvider by myself, the TestBuilder.php is creating one but it relies on autoloaded data, that seems to not being created.
Any hints on this would be great.
Repro case
Here is windows powershell repro case for a docker linux container setup that fully replicates the issue. Just put it into an empty dir and execute it.
Set-StrictMode -Version 3
$outDir = "$PSScriptRoot/out_dir"
if(Test-Path $outDir)
{
Remove-Item -Force -Recurse $outDir | Out-Null
}
New-Item -ItemType Directory $outDir | Out-Null
@'
{
"name": "root/app",
"require-dev": {
"phpunit/phpunit": "^10"
}
}
'@ | Out-File $outDir\composer.json -Encoding ascii
docker run --volume "$($outDir):/app" --rm -it composer/composer composer update
@'
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class EmailTest extends TestCase
{
public function testCanBeCreatedFromValidEmail(): void
{
$this->assertSame("foo", "foo");
}
}
'@ | Out-File $outDir\EmailTest.php -Encoding ascii
docker run --volume "$($outDir):/app" --rm -it composer/composer ./vendor/bin/phpunit EmailTest.php
答案1
得分: 3
我最近在laravel 10中遇到了相同的问题,但我通过将"phpunit"版本降级到"10.0.1"来解决了它。
英文:
I had the same issue recently with laravel 10, but i fixed it by downgrading the "phpunit" version to "10.0.1".
答案2
得分: 0
我在GitHub上将此问题记录为phpunit的问题。
它被关闭为不是问题,但线程中的评论值得阅读,并提供了降级的替代解决方案。
https://github.com/sebastianbergmann/phpunit/issues/5477
a) 使用基于类映射的自动加载
b) 添加psr-4类加载的解决方法
"autoload-dev": {
"psr-4": {
"PHPUnit\\Metadata\\": "vendor/phpunit/phpunit/src/Metadata",
"PHPUnit\\Metadata\\Annotation\\Parser\\": "vendor/phpunit/phpunit/src/Metadata/Parser/Annotation"
}
}
英文:
I logged this as an issue for phpunit on github.
It was closed as not an issue, but the comments in the thread are worth reading and provide alternative solutions to downgrading
https://github.com/sebastianbergmann/phpunit/issues/5477
a) Use classmap-based autoloading
b) Add psr-4 classloading work-arounds
"autoload-dev": {
"psr-4": {
"PHPUnit\\Metadata\\": "vendor/phpunit/phpunit/src/Metadata",
"PHPUnit\\Metadata\\Annotation\\Parser\\": "vendor/phpunit/phpunit/src/Metadata/Parser/Annotation"
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论