وحدة اختبار طلبات HTTP في c#




.net unit-testing (3)

إذا كان السخرية من HttpWebRequest و HttpWebResponse تصبح مرهقة للغاية ، أو إذا احتجت في أي وقت لاختبار الرمز في اختبار القبول ، حيث تقوم باستدعاء شفرتك من "خارج" ، فمن المحتمل أن يكون إنشاء خدمة مزيفة هو أفضل طريقة للذهاب.

لقد قمت بالفعل بكتابة مكتبة مفتوحة المصدر تسمى MockHttpServer للمساعدة في ذلك ، مما يجعل من السهل جدًا MockHttpServer أي خدمات خارجية تتواصل عبر HTTP.

في ما يلي مثال على استخدامه مع RestSharp للاتصال بنقطة نهاية API معه ، ولكن HttpWebRequest سيعمل كذلك.

using (new MockServer(3333, "/api/customer", (req, rsp, prm) => "Result Body"))
{
    var client = new RestClient("http://localhost:3333/");
    var result = client.Execute(new RestRequest("/api/customer", Method.GET));
}

هناك مقالة تفصيلية إلى حد ما على صفحة GitHub التي تمر عبر جميع الخيارات المتاحة لاستخدامها ، والمكتبة نفسها متاحة من خلال NuGet.

أنا أكتب بعض التعليمات البرمجية التي تستدعي خدمة ويب ، وتعيد الاستجابة وتنفذ شيئًا بها. يبدو الرمز الخاص بي على هذا النحو:

string body = CreateHttpBody(regularExpression, strategy);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
request.Method = "POST";
request.ContentType = "text/plain; charset=utf-8";

using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(Encoding.UTF8.GetBytes(body), 0, body.Length);
    requestStream.Flush();
}

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    byte[] data = new byte[response.ContentLength];

    using (Stream stream = response.GetResponseStream())
    {
        int bytesRead = 0;

        while (bytesRead < data.Length)
        {
            bytesRead += stream.Read(data, bytesRead, data.Length - bytesRead);
        }
    }

    return ExtractResponse(Encoding.UTF8.GetString(data));
}

الأجزاء الوحيدة التي أقوم فيها بالفعل بأي معالجة مخصصة موجودة في أساليب CreateHttpBody و CreateHttpBody . ومع ذلك ، فإنه من الخطأ أن تقوم الوحدة فقط باختبار هذه الطرق ، ونأمل أن يتم تجميع بقية الشفرات بشكل صحيح. هل هناك طريقة يمكن بها اعتراض طلب HTTP وإطعامه بطريقة وهمية بدلا من ذلك؟

EDIT هذه المعلومات غير محدثة الآن. من الأسهل إنشاء هذا النوع من التعليمات البرمجية باستخدام مكتبات System.Net.Http.HttpClient .


إذا كنت سعيدًا بالانتقال إلى HttpClient (مكتبة عميل رسمية ، محمولة ، أو http) ، MockHttp بكتابة مكتبة مرة أخرى قد تساعد في استدعاء MockHttp . فهو يوفر واجهة برمجة تطبيقات بطلاقة تتيح لك تقديم ردود للطلبات المتطابقة باستخدام مجموعة من السمات.


في التعليمات البرمجية الخاصة بك لا يمكنك اعتراض المكالمات إلى HttpWebRequest لأنك إنشاء الكائن في نفس الأسلوب. إذا سمحت كائن آخر بإنشاء HttpWebRequest ، يمكنك تمرير في كائن وهمية واستخدام ذلك لاختبار.

لذلك بدلا من هذا:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);

استخدم هذا:

IHttpWebRequest request = this.WebRequestFactory.Create(_url);

في اختبار وحدة الخاص بك ، يمكنك تمرير في WebRequestFactory الذي يخلق كائن وهمي.

علاوة على ذلك ، يمكنك تقسيم شفرة قراءة الدفق في وظيفة منفصلة:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    byte[] data = ReadStream(response.GetResponseStream());
    return ExtractResponse(Encoding.UTF8.GetString(data));
}

هذا يجعل من الممكن اختبار ReadStream() بشكل منفصل.

للقيام بالمزيد من اختبار التكامل ، يمكنك إعداد خادم HTTP الخاص بك والذي يقوم بإرجاع بيانات الاختبار ، وتمرير عنوان URL الخاص بهذا الخادم إلى طريقتك.





unit-testing