Mockery for PHP: Complete Guide with Examples
1. What Is Mockery and Why You Need It
Mockery is a powerful and flexible PHP library for creating mock objects. Designed for unit testing, it lets developers isolate the code under test from its dependencies. Instead of using real objects (like database connections, API clients, or the filesystem), you create "stubs" (mocks) that mimic the behavior of the originals. This makes your tests fast, reliable, and independent of external factors.
Why is this important? Imagine you're testing an OrderProcessor class that sends an email after an order is placed. If you use a real Mailer, your test will be slow, depend on whether the SMTP server is working, and might accidentally send emails to real users. With Mockery, you create a "fake" Mailer that simply checks whether the send() method was called with the right arguments. This lets you focus on the OrderProcessor logic, not the infrastructure.
Mockery is more than just object replacement. It provides a rich API for defining expectations: you can specify how many times a method should be called, with which arguments, in what order, and what it should return. This makes your tests not only isolated but also self-documenting, as the expectations clearly describe the interaction between objects.
2. Installation
Mockery is installed via Composer, the standard PHP package manager. It's recommended to add it as a development dependency (require-dev), since it's not needed in production.
composer require --dev mockery/mockery
After installation, make sure your composer.json file includes the following entry in the require-dev section:
{
"require-dev": {
"mockery/mockery": "^1.6"
}
}
If you're using PHPUnit, Mockery integrates out of the box via the \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration trait.
3. Quick Start
Let's create a simple test that demonstrates Mockery's basic functionality. Suppose we have a Calculator class that depends on a Logger service.
<?php
// Example classes
interface Logger {
public function log(string $message): void;
}
class Calculator {
private Logger $logger;
public function __construct(Logger $logger) {
$this->logger = $logger;
}
public function add(int $a, int $b): int {
$result = $a + $b;
$this->logger->log("Adding $a and $b, result: $result");
return $result;
}
}
// Test using Mockery
use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
class CalculatorTest extends TestCase {
use MockeryPHPUnitIntegration;
public function testAddLogsCorrectly(): void {
// 1. Create a mock for Logger
$loggerMock = Mockery::mock(Logger::class);
// 2. Define the expectation: log() should be called once
// with a specific message
$loggerMock->shouldReceive('log')
->once()
->with('Adding 2 and 3, result: 5');
// 3. Create the object under test with the mock
$calculator = new Calculator($loggerMock);
// 4. Also in library
NHibernate for C# (.NET): Complete Guide with Examples
iTextSharp for C# (.NET): Complete Guide with Examples
TypeStack/class-validator for TypeScript: Complete Guide with Examples
Rate Limiting in Kotlin: Libraries and Practical Examples
Data Validation in Swift (iOS/macOS): Libraries and Approaches