Prophecy PHP: Complete Guide with Examples
1. What Is Prophecy and Why Use It
Prophecy is a powerful object mocking library for PHP. It provides an elegant, expressive, and flexible API for creating test stubs, spies, and fake objects that mimic the behavior of real dependencies in unit tests. Unlike many other libraries, Prophecy focuses on "prophecies" — you describe how an object should behave, and the library automatically generates the implementation.
The main goal of Prophecy is to make writing unit tests as simple and readable as possible. Instead of manually creating complex mock objects with tons of configuration, you simply "declare a prophecy" for the class or interface you need, then call the methods that should be invoked in the code under test. Prophecy automatically checks whether the actual calls match your expectations.
This library is especially useful when testing code that depends on external services (databases, APIs, file systems), complex objects, or objects with side effects. Prophecy lets you isolate the code under test by replacing real dependencies with predictable stubs. It's the de facto standard for many PHP frameworks, including Symfony and Laravel, and is used in popular projects like Doctrine and PHPUnit (via integration).
2. Installation
Prophecy is installed via Composer, the standard dependency manager for PHP. Run the following command in your project root:
composer require --dev phpspec/prophecy
The --dev flag means the library will only be added to the require-dev section of your composer.json, since Prophecy is needed exclusively for testing and should not be used in production environments.
If you're using PHPUnit, it's also recommended to install the integration package for seamless Prophecy support:
composer require --dev phpspec/prophecy-phpunit
After installation, make sure the vendor/autoload.php file is included in your test file (this is usually handled automatically by PHPUnit).
3. Quick Start — Minimal Working Example
Let's write a simple test using Prophecy. Suppose we have a UserMailer class that sends a welcome email to a new user. It depends on a MailerInterface.
<?php
// Classes under test
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,
'Welcome!',
'Thank you for joining!'
);
}
}
// Test using Prophecy
use Prophecy\PhpUnit\ProphecyTrait;
use PHPUnit\Framework\TestCase;
class UserMailerTest extends TestCase {
use ProphecyTrait;
public function testSendWelcomeEmail() {
// 1. Create a prophecy for MailerInterface
$mailerProphecy = $this->prophesize(MailerInterface::class);
// 2. Declare an expectation: the send method will be called once with specific arguments
$mailerProphecy->send('user@example.com', 'Welcome!', 'Thank you for joining!')
->willReturn(true);
// 3. Get the mock object from the prophecy
$mailerMock = $mailerProphecy- Also in library
Working with Excel in PHP: PhpSpreadsheet, PhpOffice Libraries and XLSX Generation
Working with XML in JavaScript (Node.js): Parsing, Creation, and Validation
Working with Excel in TypeScript: Libraries, Tools, and Code Examples
Parsing HTML in Java: Best Libraries and Code Examples