Mockery PHP: دليل شامل مع أمثلة عملية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Mockery PHP: دليل شامل مع أمثلة عملية

1. ما هي Mockery ولماذا تحتاجها؟

Mockery هي مكتبة قوية ومرنة لإنشاء كائنات وهمية (mock objects) في PHP. صُممت لاستخدامها في اختبار الوحدة (unit testing) وتتيح للمطورين عزل الكود المختبر عن تبعياته. بدلاً من استخدام كائنات حقيقية (مثل اتصال قاعدة البيانات، عملاء API، أو نظام الملفات)، يمكنك إنشاء "نماذج بديلة" (mocks) تحاكي سلوك الكائنات الأصلية. هذا يجعل الاختبارات سريعة وموثوقة ومستقلة عن العوامل الخارجية.

لماذا تحتاجها؟ تخيل أنك تختبر كلاس OrderProcessor الذي يرسل بريدًا إلكترونيًا بعد تأكيد الطلب. إذا استخدمت كلاس Mailer الحقيقي، سيصبح اختبارك بطيئًا، وسيعتمد على توفر خادم SMTP، وقد يرسل رسائل بريد إلكتروني لمستخدمين حقيقيين عن طريق الخطأ. باستخدام Mockery، يمكنك إنشاء Mailer "مزيف" يتحقق ببساطة مما إذا تم استدعاء الدالة send() بالوسائط الصحيحة. هذا يسمح لك بالتركيز على منطق OrderProcessor بدلاً من البنية التحتية.

Mockery ليست مجرد بديل للكائنات. فهي توفر واجهة برمجية غنية لوصف التوقعات (expectations): يمكنك تحديد عدد مرات استدعاء الدالة، والوسائط التي يجب أن تُمرر، والترتيب، والقيمة التي يجب أن تعيدها. هذا يجعل الاختبارات ليس فقط معزولة، بل أيضًا موثقة ذاتيًا، حيث تصف التوقعات بوضوح التفاعل بين الكائنات.

2. التثبيت

يتم تثبيت Mockery عبر Composer، مدير الحزم القياسي لـ PHP. يُنصح بتثبيتها كتبعية للتطوير (require-dev) لأنها غير مطلوبة في بيئة الإنتاج.

composer require --dev mockery/mockery

بعد التثبيت، تأكد من أن ملف composer.json يحتوي على الإدخال التالي في قسم require-dev:

{
    "require-dev": {
        "mockery/mockery": "^1.6"
    }
}

إذا كنت تستخدم PHPUnit، فإن Mockery تتكامل معه "فورًا" من خلال trait \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration.

3. البداية السريعة

لنقم بإنشاء اختبار بسيط يوضح الوظائف الأساسية لـ Mockery. لنفترض أن لدينا كلاس Calculator يعتمد على خدمة Logger.

<?php
// كلاسات المثال
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("جمع $a و $b، النتيجة: $result");
        return $result;
    }
}

// الاختبار باستخدام Mockery
use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;

class CalculatorTest extends TestCase {
    use MockeryPHPUnitIntegration;

    public function testAddLogsCorrectly(): void {
        // 1. إنشاء كائن وهمي لـ Logger
        $loggerMock = Mockery::mock(Logger::class);

        // 2. وصف التوقع: يجب استدعاء الدالة log() مرة واحدة
        //    برسالة محددة
        $loggerMock->shouldReceive('log')
            ->once()
            ->with('جمع 2 و 3، النتيجة: 5');

        // 3. إنشاء الكائن المختبر باستخدام الكائن الوهمي
        $calculator = new Calculator($loggerMock);

        // 4.                    

توصيات