WireMock.Net لـ C# (.NET): دليل شامل مع أمثلة عملية

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

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

ابدأ الدورة

WireMock.Net لـ C# (.NET): الدليل الشامل

1. ما هي WireMock.Net ولماذا نحتاجها؟

WireMock.Net هي مكتبة قوية لإنشاء خوادم HTTP وهمية (mock servers) في بيئة .NET. وهي تمثل التطبيق العملي لمشروع WireMock الشهير بلغة Java بلغة C#. المهمة الأساسية للمكتبة هي محاكاة سلوك خدمات HTTP/HTTPS الحقيقية (مثل REST API, SOAP, gRPC) أثناء الاختبار أو التطوير.

لماذا نحتاجها؟ في عالم تطبيقات الخدمات المصغرة (microservices)، يعتمد تطبيقك غالبًا على عشرات الـ APIs الخارجية. استخدام الخدمات الحقيقية في اختبارات الوحدة أو التكامل يؤدي إلى مشاكل عديدة: عدم استقرار الاختبارات بسبب تعطل الخادم، بطء الأداء، تكاليف مالية لاستدعاء APIs مدفوعة، واستحالة اختبار سيناريوهات نادرة (مثل خطأ 500 أو انتهاء المهلة). WireMock.Net تحل هذه المشاكل بالسماح لك بـ "استبدال" الخدمة الخارجية محليًا.

حالات الاستخدام الرئيسية: اختبار وحدات عملاء HTTP (HttpClient)، اختبار تكامل تطبيقات الويب، التطوير "بدون اتصال" (عندما لا يكون الخادم الخلفي جاهزًا بعد)، اختبار معالجة الأخطاء وانتهاء المهلة، وإنشاء بيئات اختبار معزولة (sandbox).

2. التثبيت

يتم توزيع المكتبة عبر NuGet. للتثبيت، استخدم أحد الأوامر التالية:

عبر .NET CLI (موصى به):

dotnet add package WireMock.Net

عبر Package Manager Console (في Visual Studio):

Install-Package WireMock.Net

لاختبارات غير متزامنة و Fluent Assertions (اختياري لكن مفيد):

dotnet add package WireMock.Net.FluentAssertions

ملاحظة: على عكس Python (pip) أو Node.js (npm)، يستخدم .NET مدير الحزم NuGet.

3. البداية السريعة — مثال عملي بسيط

أنشئ تطبيق وحدة تحكم (Console App) أو مشروع اختبار (xUnit/NUnit). فيما يلي كود بسيط يشغل خادمًا وهميًا على المنفذ 9876، ويعيد استجابة JSON لطلب GET.

using WireMock.Server;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;

// 1. تشغيل الخادم (افتراضيًا على منفذ عشوائي، لكننا سنحدد منفذًا معينًا)
var server = WireMockServer.Start(9876);

// 2. إعداد الاستجابة الوهمية (stub)
server.Given(
    Request.Create()
        .WithPath("/api/users/1")
        .UsingGet()
)
.RespondWith(
    Response.Create()
        .WithStatusCode(200)
        .WithHeader("Content-Type", "application/json")
        .WithBody("{ \"id\": 1, \"name\": \"John Doe\" }")
);

Console.WriteLine($"الخادم الوهمي يعمل على {server.Urls[0]}");
Console.WriteLine("اضغط أي مفتاح للإيقاف...");
Console.ReadKey();

// 3. إيقاف الخادم
server.Stop();

بعد التشغيل، افتح المتصفح أو استخدم curl: curl http://localhost:9876/api/users/1. ستحصل على استجابة JSON.

4. أهم الدوال/الكلاسات

4.1. WireMockServer.Start()

التوقيع: public static WireMockServer Start(int? port = null, bool ssl = false)

الوصف: دالة ثابتة تنشئ وتشغل مثيلًا من الخادم الوهمي. إذا لم يتم تحديد المنفذ، يتم اختيار منفذ عشوائي متاح.

// التشغيل على المنفذ 5000
var server = WireMockServer.Start(5000);

// التشغيل على منفذ عشوائي
var serverRandom = WireMockServer.Start();

4.2. server.Given()

التوقيع: public IRespondWithAwareResponseBuilder Given

الوصف: دالة تُستخدم لتعريف قاعدة (stub) جديدة. تأخذ كائن طلب (Request) وتعيد كائن استجابة (Response) لتحديد كيفية الرد.

server.Given(
    Request.Create()
        .WithPath("/api/items")
        .UsingPost()
        .WithBody("{\"name\":\"test\"}")
)
.RespondWith(
    Response.Create()
        .WithStatusCode(201)
        .WithBody("{\"id\": 1, \"name\": \"test\"}")
);

4.3. Request.Create()

الوصف: دالة static لإنشاء كائن طلب جديد. يمكن تخصيصه باستخدام دوال مثل WithPath(), UsingGet(), WithHeader(), WithBody().

var request = Request.Create()
    .WithPath("/api/users/*") // استخدام wildcard
    .UsingGet()
    .WithHeader("Authorization", "Bearer *"); // تطابق أي توكن

4.4. Response.Create()

الوصف: دالة static لإنشاء كائن استجابة. يمكن تخصيصه باستخدام دوال مثل WithStatusCode(), WithHeader(), WithBody(), WithDelay().

var response = Response.Create()
    .WithStatusCode(200)
    .WithHeader("Content-Type", "application/json")
    .WithBody("{\"status\":\"ok\"}")
    .WithDelay(TimeSpan.FromMilliseconds(500)); // محاكاة تأخير الشبكة

4.5. server.Stop() & server.Reset()

الوصف: Stop() يوقف الخادم. Reset() يمسح جميع الـ stubs المحددة دون إيقاف الخادم.

// إيقاف الخادم
server.Stop();

// إعادة تعيين جميع القواعد دون إيقاف الخادم
server.Reset();

توصيات