Prophecy PHP 完整指南:从入门到实战
1. 什么是 Prophecy?为什么需要它?
Prophecy 是一个强大的 PHP 对象模拟(Mock)库,用于创建优雅、灵活且表达力强的测试替身。它允许你通过“预言”(prophecy)的方式描述对象的行为,然后由库自动生成对应的 Mock 对象、间谍(Spy)或桩(Stub),从而在单元测试中模拟真实依赖的行为。与许多其他 Mock 库不同,Prophecy 让你专注于“声明预期”——你只需描述对象应该如何表现,库就会自动实现。
Prophecy 的核心目标是让编写单元测试变得极其简单和易读。你无需手动配置复杂的 Mock 对象,只需为所需的类或接口“声明一个预言”,然后调用测试代码中预期会调用的方法。Prophecy 会自动验证实际调用是否与你的预期匹配。
该库在测试依赖外部服务(如数据库、API、文件系统)、复杂对象或具有副作用的对象时尤为有用。Prophecy 通过用可预测的替身替换真实依赖,帮助你隔离被测试的代码。它已成为许多 PHP 框架(包括 Symfony 和 Laravel)的事实标准,并被用于 Doctrine 和 PHPUnit(通过集成)等流行项目中。
2. 安装 Prophecy
Prophecy 通过 Composer(PHP 的标准依赖管理器)安装。在项目根目录下执行以下命令:
composer require --dev phpspec/prophecy
--dev 标志表示该库仅添加到 composer.json 的 require-dev 部分,因为 Prophecy 仅用于测试,不应在生产环境中使用。
如果你使用 PHPUnit,建议同时安装集成包以实现自动支持:
composer require --dev phpspec/prophecy-phpunit
安装后,请确保测试文件中已引入 vendor/autoload.php(PHPUnit 通常会自动处理)。
3. 快速上手:最小工作示例
让我们编写一个使用 Prophecy 的简单测试。假设我们有一个 UserMailer 类,它负责向新用户发送欢迎邮件,并依赖于 MailerInterface 接口。
<?php
// 待测试的类
interface MailerInterface {
public function send(string $to, string $subject, string $body): bool;
}
class UserMailer {
private $mailer;
public function __construct(MailerInterface $mailer) {
$this->mailer = $mailer;
}
public function sendWelcomeEmail(string $email): bool {
return $this->mailer->send(
$email,
'欢迎加入!',
'感谢您的注册!'
);
}
}
// 使用 Prophecy 的测试
use Prophecy\PhpUnit\ProphecyTrait;
use PHPUnit\Framework\TestCase;
class UserMailerTest extends TestCase {
use ProphecyTrait;
public function testSendWelcomeEmail() {
// 1. 为 MailerInterface 创建预言
$mailerProphecy = $this->prophesize(MailerInterface::class);
// 2. 声明预期:send 方法将被调用一次,并传入指定参数
$mailerProphecy->send('user@example.com', '欢迎加入!', '感谢您的注册!')
->willReturn(true);
// 3. 从预言中获取 Mock 对象
$mailerMock = $mailerProphecy-