使用PHPUnit+Prophecy测试遇'Prophecy\Prophet'未找到及依赖安装失败求助
问题分析
你遇到的两个问题其实是关联的:
- Prophecy类未找到:你提到“PHPUnit应该内置支持Prophecy”,这个说法在PHPUnit 8及以下版本是成立的,但从PHPUnit 9.x开始,Prophecy不再是PHPUnit的核心依赖,需要单独安装。这就是测试时出现
Class 'Prophecy\Prophet' not found的根本原因。 - Composer依赖冲突:安装
phpspec/prophecy失败,是因为你的项目锁定了doctrine/instantiator:1.1.0,而你要求安装的PHPUnit 9.x需要doctrine/instantiator:^1.2.0,两者版本不兼容导致冲突。
解决方案一:更新依赖以兼容PHPUnit 9 + 单独安装Prophecy
这是更推荐的方案,既能保留新版本PHPUnit,又能解决依赖问题:
- 首先更新
doctrine/instantiator到兼容PHPUnit 9的版本,同时同步更新相关依赖:
composer update doctrine/instantiator --with-dependencies
这个命令会自动把doctrine/instantiator升级到1.2.0或更高兼容版本,同时调整其他依赖的版本来匹配要求。
- 然后安装Prophecy作为开发依赖:
composer require --dev phpspec/prophecy
完成后,你的测试代码还需要补充一个小细节:创建预言后要调用reveal()方法获取可用实例,比如:
public function testItBuildsAndPersistsEnclosure() { $emProphecy = $this->prophesize(EntityManagerInterface::class); // 这里可以添加对EntityManager方法的预言,比如: // $emProphecy->persist(Argument::type(Enclosure::class))->shouldBeCalled(); $em = $emProphecy->reveal(); // 获取可用于测试的实例 // 后续使用$em完成测试逻辑 }
解决方案二:降级PHPUnit到8.x版本(无需单独安装Prophecy)
如果你暂时不想更新现有依赖,可以把PHPUnit降级到8.x版本——这个版本仍然内置Prophecy,同时和doctrine/instantiator:1.1.0完全兼容:
composer require --dev phpunit/phpunit:^8.0
执行完这个命令后,你原来的测试代码不需要任何修改,就能直接使用Prophecy的API了。
附:你遇到的错误信息及代码参考
你的测试代码:
public function testItBuildsAndPersistsEnclosure() { $em = $this->prophesize(EntityManagerInterface::class); }
测试运行时的错误输出:
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.
Testing Project Test Suite
E. 2 / 2 (100%)
Time: 105 ms, Memory: 6.00MBThere was 1 error:
- Tests\AppBundle\Service\EnclosureBuilderServiceProphecyTest::testItBuildsAndPersistsEnclosure
Error: Class 'Prophecy\Prophet' not found
安装Prophecy时的依赖冲突信息:
composer require phpspec/prophecy
Using version ^1.10 for phpspec/prophecy
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.Problem 1
- Conclusion: don't install phpunit/phpunit 9.0.1
- Conclusion: remove doctrine/instantiator 1.1.0
- Installation request for phpunit/phpunit ^9.0 -> satisfiable by phpunit/phpunit[9.0.0, 9.0.1].
- Conclusion: don't install doctrine/instantiator 1.1.0
- phpunit/phpunit 9.0.0 requires doctrine/instantiator ^1.2.0 -> satisfiable by doctrine/instantiator[1.2.0, 1.3.0].
- Can only install one of: doctrine/instantiator[1.2.0, 1.1.0].
- Can only install one of: doctrine/instantiator[1.3.0, 1.1.0].
- Installation request for doctrine/instantiator (locked at 1.1.0) -> satisfiable by doctrine/instantiator[1.1.0].
Installation failed, reverting ./composer.json to its original content.
内容的提问来源于stack exchange,提问作者sisko

