دليل شامل لـ mockall في Rust: أمثلة وطرق الاستخدام

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

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

ابدأ الدورة

دليل شامل لـ mockall في Rust: أمثلة وطرق الاستخدام

1. ما هي مكتبة mockall ولماذا تحتاجها؟

مكتبة mockall هي إطار عمل قوي لإنشاء كائنات وهمية (mock objects) تلقائيًا في لغة Rust. صُممت هذه المكتبة لاختبار الوحدات (unit testing)، وتتيح للمطورين عزل الكود المختبر عن الاعتماديات الخارجية مثل قواعد البيانات، عملاء HTTP، أنظمة الملفات، أو أي خدمات أخرى. على عكس كتابة النماذج البديلة يدويًا، تقوم mockall بإنشاء هياكل وهمية تلقائيًا بناءً على الـ traits الموجودة، وتوفر واجهة برمجة تطبيقات (API) مرنة لتعيين التوقعات (expectations) والتحقق من الاستدعاءات.

لماذا تحتاج إليها؟ في المشاريع الحقيقية، نادرًا ما يعمل الكود في فراغ. الدوال تستدعي دوالًا أخرى، والوحدات تعتمد على مكتبات خارجية. عند اختبار وحدة معينة، لا نريد أن يعتمد الاختبار على عمل قاعدة البيانات أو الشبكة. تحل mockall هذه المشكلة عن طريق إنشاء كائنات وهمية تحاكي سلوك الاعتماديات الحقيقية. يمكنك تحديد ما يجب أن يعيده الأسلوب (method) عند استدعائه بوسائط معينة، وعدد مرات استدعائه، وحتى التحقق من ترتيب الاستدعاءات. هذا يجعل الاختبارات سريعة وموثوقة وقابلة للتكرار.

الميزة الأساسية لـ mockall هي تكاملها مع نظام الأنواع في Rust وعملها في مرحلة الترجمة من خلال الخاصية #[automock]. هذا يعني أن الكائنات الوهمية تُنشأ تلقائيًا لأي trait، مما يوفر وقتًا كبيرًا ويقلل من الكود المتكرر. تدعم المكتبة الدوال غير المتزامنة (async functions)، الأنواع العامة (generics)، الـ traits ذات الأنواع المرتبطة (associated types)، وغيرها الكثير، مما يجعلها أداة لا غنى عنها للتطوير الجاد في Rust.

2. طريقة التثبيت

لاستخدام mockall في مشروع Rust الخاص بك، أضف التبعية إلى ملف Cargo.toml. يتم تثبيت المكتبة عبر مدير الحزم القياسي Cargo. يُنصح بإضافتها فقط كـ dev-dependency، لأنها تُستخدم حصريًا للاختبار.


# Cargo.toml
[dev-dependencies]
mockall = "0.13"  # استخدم أحدث إصدار متاح عند القراءة
        

بعد إضافة السطر، قم بتشغيل الأمر cargo build أو cargo test ليقوم Cargo بتحميل المكتبة وترجمتها. إذا كنت تعمل في مشروع به تبعيات أخرى، تأكد من توافق إصدار mockall مع إصدار Rust لديك (عادةً ما يتطلب Rust 1.70+). للتحقق من أحدث إصدار، زر crates.io/crates/mockall.

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

لننشئ مثالًا عمليًا بسيطًا. لنفترض أن لدينا trait باسم Greeter نريد إنشاء كائن وهمي له في الاختبار. باستخدام #[automock]، نحصل تلقائيًا على هيكل MockGreeter.


// src/lib.rs
use mockall::automock;

#[automock]
pub trait Greeter {
    fn greet(&self, name: &str) -> String;
}

pub fn run_greeter(greeter: &impl Greeter, name: &str) -> String {
    greeter.greet(name)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_greeting() {
        // إنشاء كائن وهمي
        let mut mock = MockGreeter::new();

        // تعيين التوقع: عند استدعاء greet("Alice")، أعد "Hello, Alice!"
        mock.expect_greet()
            .with(predicate::eq("Alice"))
            .returning(|name| format!("Hello, {}!", name));

        // استدعاء الدالة المختبرة
        let result = run_greeter(&mock, "Alice");

        // التحقق من النتيجة
        assert_eq!(result, "Hello, Alice!");
    }
}
        

قم بتشغيل الاختبار باستخدام الأمر cargo test. إذا كان كل شيء مضبوطًا بشكل صحيح، سينجح الاختبار.

توصيات