wiremock-rs: خادم HTTP وهمي (Mock) للغة Rust
في تطوير البرمجيات الحديث، يُعد الاختبار جزءًا لا يتجزأ من العملية. من الصعب بشكل خاص اختبار الكود الذي يتفاعل مع خدمات HTTP الخارجية. هنا تأتي مكتبة wiremock-rs كأداة قوية لإنشاء خوادم HTTP وهمية (Mock Servers) في نظام Rust البيئي.
تتيح لك wiremock-rs محاكاة سلوك خدمات HTTP الخارجية، مما يسمح للمطورين باختبار كودهم في بيئة معزولة. بدلاً من إرسال طلبات حقيقية إلى واجهات برمجية خارجية (API) – والتي قد تكون بطيئة أو غير موثوقة أو مكلفة – يمكنك إنشاء خادم وهمي محلي يستجيب تمامًا كما تحدد. هذا مفيد بشكل خاص عند كتابة اختبارات التكامل، واختبار معالجة الأخطاء، وتطوير مكتبات العميل.
المكتبة مستوحاة من الأداة الشهيرة WireMock بلغة Java، ولكنها أعيدت كتابتها بالكامل بلغة Rust مع مراعاة قواعد اللغة وخصائصها. تدعم wiremock-rs جميع الميزات الأساسية: مطابقة الطلبات حسب URL، والروؤس (Headers)، والجسم (Body)؛ وإرجاع حالات HTTP مختلفة؛ وتأخير الاستجابات؛ والتحقق من عدد الاستدعاءات، وغير ذلك الكثير.
التثبيت
لتثبيت wiremock-rs، أضف التبعية إلى ملف Cargo.toml الخاص بك:
[dev-dependencies]
wiremock = "0.6"
ثم نفذ الأمر التالي:
cargo build
تأكد أيضًا من تثبيت Rust و Cargo. إذا لم يكن مثبتًا، قم بتثبيتهما عبر rustup.
بداية سريعة
لنقم بإنشاء خادم وهمي بسيط يستجيب لطلبات GET:
use wiremock::{MockServer, Mock, ResponseTemplate};
use wiremock::matchers::{method, path};
#[tokio::main]
async fn main() {
// تشغيل الخادم الوهمي على منفذ عشوائي
let mock_server = MockServer::start().await;
// إنشاء قاعدة: على GET /hello نرد بحالة 200 ونص "Hello, World!"
let mock = Mock::given(method("GET"))
.and(path("/hello"))
.respond_with(ResponseTemplate::new(200)
.set_body_string("Hello, World!"));
// تسجيل القاعدة على الخادم
mock_server.register(mock).await;
// الآن يمكننا إرسال طلبات إلى الخادم
let client = reqwest::Client::new();
let response = client.get(&format!("{}/hello", &mock_server.uri()))
.send()
.await
.unwrap();
println!("الحالة: {}", response.status());
println!("النص: {}", response.text().await.unwrap());
// إيقاف الخادم (سيحدث تلقائيًا عند انتهاء main)
}
يوضح هذا المثال البسيط الفكرة الأساسية: تقوم بتشغيل خادم، وتحدد القواعد (matchers) والاستجابات (response templates)، ثم تسجلها. بعد ذلك، يمكن لكود العميل الخاص بك إرسال طلبات إلى الخادم الوهمي.
الطرق والوظائف الرئيسية
1. MockServer::start()
التوقيع: pub async fn start() -> MockServer
الوصف: يقوم بتشغيل خادم وهمي جديد على منفذ عشوائي متاح. سيظل الخادم يعمل حتى يتم حذف كائن MockServer.
let server = MockServer::start().await;
println!("الخادم يعمل على {}", server.uri());
2. MockServer::start_on_port(port: u16)
التوقيع: pub async fn start_on_port(port: u16) -> MockServer
الوصف: يقوم بتشغيل الخادم الوهمي على منفذ محدد. مفيد عندما تحتاج إلى منفذ ثابت للتكوين.
let server = MockServer::start_on_port(8080).await;
assert_eq!(server.uri(), "http://127.0.0.1:8080");
3. Mock::given(matcher: impl Matcher)
التوقيع: pub fn given(matcher: impl Matcher) ->