جعل الكود داخليًا ولكن متاحًا لاختبار الوحدة من المشاريع الأخرى

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

  •  01-07-2019
  •  | 
  •  

سؤال

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

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

المحلول

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

لاحظ أنه يجب استخدام هذا بحذر لأنه يربط التجميعات المعنية بإحكام.الاستخدام الشائع لـ InternalsVisibleTo هو لمشاريع اختبار الوحدة.ربما لا يكون هذا خيارًا جيدًا للاستخدام في تجميعات التطبيقات الفعلية الخاصة بك، للسبب المذكور أعلاه.

مثال:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{

نصائح أخرى

إذا كانت فئة داخلية، فلا يجب استخدامها بمعزل عن غيرها.لذلك لا ينبغي عليك اختباره حقًا بصرف النظر عن اختبار فئة أخرى تستخدم هذا الكائن داخليًا.

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

الفكرة هي أنك تريد فقط اختبار سلوك الفصل الدراسي لأنه إذا اختبرت تفاصيل التنفيذ الداخلي، فستكون اختباراتك هشة.يجب أن تكون قادرًا على تغيير تفاصيل تنفيذ أي فصل دون كسر جميع اختباراتك.

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

لأغراض التوثيق

وبدلاً من ذلك يمكنك إنشاء مثيل للفصل الداخلي باستخدام Type.GetType طريقة

مثال

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
    .CreateInstance(type, new object[1] { /*constructor parameter*/ });

بالنسبة للنوع العام هناك عملية مختلفة كما يلي:

var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
     .CreateInstance(genType, new object[1] { /*constructor parameter*/});

يمكن أن تكون الفصول عامة ومختومة.

لكن لا تفعل ذلك.

يمكنك إنشاء أداة للتفكير في الفئات الداخلية، وإصدار فئة جديدة تصل إلى كل شيء من خلال التفكير.MSTest يفعل ذلك.

يحرر:أعني، إذا كنت لا ترغب في تضمين -أي- عناصر اختبار في التجميع الأصلي الخاص بك؛يعمل هذا أيضًا إذا كان الأعضاء خاصين.

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