DbConnection بدون Db باستخدام DataSet في الذاكرة (أو ما شابه) كمصدر

StackOverflow https://stackoverflow.com/questions/683395

  •  22-08-2019
  •  | 
  •  

سؤال

أحاول إجراء اختبار موحد لعدد قليل من فئات .NET التي (لأسباب تصميمية جيدة) تتطلب DbConnections للقيام بعملها.بالنسبة لهذه الاختبارات، لدي بيانات معينة في الذاكرة لأقدمها كمدخلات لهذه الفئات.

يمكن التعبير عن تلك البيانات الموجودة في الذاكرة بسهولة على أنها DataTable (أو DataSet التي تحتوي على DataTable)، ولكن إذا كانت فئة أخرى أكثر ملاءمة فيمكنني استخدامها.

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

هل كانت مفيدة؟

المحلول

بدلاً من استهلاك DbConnection، هل يمكنك استهلاك IDbConnection والاستهزاء به؟نحن نفعل شيئًا مشابهًا، ونمرر مجموعة بيانات وهمية.يقوم DataSet.CreateDataReader بإرجاع DataTableReader الذي يرث من DbDataReader.

لقد قمنا بتغليف DbConnection في الواجهة المشابهة لـ IDbConnection والتي أضفنا إليها أسلوب ExecuteReader() الذي يُرجع فئة تنفذ نفس الواجهات مثل DbDataReader.في نموذجنا النموذجي، يقوم ExecuteReader ببساطة بإرجاع ما يقدمه DataSet.CreateDataReader.

يبدو الأمر وكأنه دوار، ولكن من الملائم جدًا إنشاء مجموعة بيانات تحتوي على العديد من مجموعات النتائج.نقوم بتسمية DataTables على اسم العمليات المخزنة التي تمثل نتائجها، ويقوم نموذج IDbConnection الخاص بنا بالحصول على Datatable الصحيح استنادًا إلى proc الذي يتصل به العميل.يقوم DataTable أيضًا بتنفيذ CreateDataReader لذا فنحن جاهزون للبدء.

نصائح أخرى

الطريقة التي استخدمتها هي إنشاء قاعدة بيانات Sqlite في الذاكرة.يمكن القيام بذلك ببساطة عن طريق سحب حزمة System.Data.SQLite.Core NuGet إلى مشروع اختبار الوحدة الخاص بك، ولن تحتاج إلى تثبيت أي برنامج في أي مكان آخر.

على الرغم من أنها تبدو فكرة واضحة حقًا، إلا أنني لم أفكر في استخدام هذه التقنية بنفسي حتى كنت أنظر إلى اختبارات وحدة Dapper!راجع طريقة "GetSqliteConnection" في

https://github.com/StackExchange/dapper-dot-net/blob/bffb0972a076734145d92959dabbe48422d12922/Dapper.Tests/Tests.cs

شيء واحد يجب أن تكون على دراية به هو أنه إذا قمت بإنشاء قاعدة بيانات sqlite في الذاكرة وقمت بإنشاء الجداول وتعبئتها، فيجب أن تكون حريصًا على عدم إغلاق الاتصال قبل إجراء استعلامات الاختبار الخاصة بك لأن فتح اتصال جديد في الذاكرة سيوفر لك اتصال ل جديد قاعدة بيانات في الذاكرة، لا قاعدة البيانات التي قمت بإعدادها بعناية لاختباراتك!بالنسبة لبعض اختباراتي، أستخدم تطبيق IDbConnection مخصصًا يبقي الاتصال مفتوحًا لتجنب هذا المأزق - على سبيل المثال.

https://github.com/ProductiveRage/SqlProxyAndReplay/blob/master/Tests/StaysOpenSqliteConnection.cs

تايبموك؟(ستحتاج إلى "تثبيته" بالرغم من ذلك).

كن حذرًا على افتراض أن Data* يمكن أن تمنحك خطافات مناسبة للاختبار - فهي أسوأ الحالات بشكل عام.لكنك تقول أسباب التصميم الجيدة، لذلك أنا متأكد من أن كل ذلك مغطى:D

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top