تركيبات. createanymous method يقتل عملية عداء الاختبار مع خطأ (autofixture) عند استخدام AutomoQ لإنشاء وحدة تحكم

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

سؤال

أحاول استخدام AutomoQCustomization مع AutoFixture لإنشاء وحدة تحكم ASP.NET MVC2 في اختبار الوحدة عبر طريقة التثبيت. لقد جربت في كل من Xunit تحت testdriven.net ، واجهة المستخدم الرسومية Xunit و MSTEST وكلها لها نفس النتيجة: فشل هائل في العملية التي تدير الاختبار. على Windows 7 X64 إذا كان ذلك مهمًا.

لإعادة إنتاج ، ببساطة إنشاء مشروع ASP.NET MVC2 جديد ، إضافة المراجع إلى AutoFixture و AutomoQ و MOQ (3.1 ، وفقًا لمصدر AutomoQ) وجرب أدناه (رابط مشروع REPRO VS2010 MVC2 أدناه):

[TestMethod]
public void Index()
{
 var fixture = new Fixture().Customize(new AutoMoqCustomization());
    // here's where the error in the test host occurs:
 HomeController controller = fixture.CreateAnonymous<HomeController>();
}

في MSTEST يقرأ الخطأ:

واجه وقت التشغيل خطأ فادح. كان عنوان الخطأ في 0x6465f370 ، على موضوع 0x2684. رمز الخطأ هو 0xC0000005. قد يكون هذا الخطأ خطأ في CLR أو في الأجزاء غير الآمنة أو غير القابلة للتحرير من رمز المستخدم. تشمل المصادر الشائعة لهذا الخطأ أخطاء حشط المستخدم لـ COM-Interop أو Pinvoke ، والتي قد تفسد المكدس.

مشروع Afwithmvc Repro (من SkyDrive)

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

المحلول

الحل المقترح

للبدء بحل ممكن ، يجب أن يوقف هذا التحطم:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
// This should fix the problem for all Controllers
fixture.Customize<ViewDataDictionary>(c =>
    c.Without(x => x.ModelMetadata));

HomeController controller = fixture.CreateAnonymous<HomeController>();

تفسير

والآن للتفسير:

يحدث خطأ الاختبار هذا بسبب AutoFixture's Autoproperties ميزة محاولة تعيين قيمة ل HomeController.ViewData.ModelMetaData. يحتوي فئة ModelMetadata على هذا المُنشئ:

public ModelMetadata(
    ModelMetadataProvider provider,
    Type containerType,
    Func<object> modelAccessor,
    Type modelType,
    string propertyName)

الجاني هنا هو modelAccessor معامل. لملء تلك الخاصية Autofixture (بلا رحمة إلى حد ما) ينعكس على النوع ويجد هذا المُنشئ المفرد:

public Func(object @object, IntPtr method)

الحفر أكثر ، يمكن أن تفي أول مُنشئ INTPTR Autofixture هو:

public unsafe IntPtr(int value)

بشكل افتراضي، يتم إنشاء مثيلات int32 من خلال تسلسل تصاعد حتمي, ، لذا value في هذه الحالة ، من المحتمل أن تكون 1 أو 2 أو عدد صحيح مماثل. بمعنى آخر ، لدينا الآن غير صالح جدا مؤشر غير آمن على أيدينا ، وهذا يجعل العملية تعطل.

الآن ، في ظل الظروف العادية ، يجب أن نكون قادرين على إصلاح هذا من خلال تسجيل أ Func<object> مع المباراة ويجب أن يكون كل شيء dandy:

fixture.Register<Func<object>>(() => () => new object());

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

لا أعرف ماذا يفعل ASP.NET MVC مع Func<object>, ، ولكن على ما يبدو أنها تستخدمه جدا.

يبقى السؤال ما إذا كان هذا خطأ في Autofixture؟

أعتقد أنه ليس كذلك. على الرغم من أنها بالتأكيد أقل من المثالية ، إلا أن Autofixture لا تعامل Funcs أو الإجراءات بشكل مختلف عن الأنواع الأخرى ، وهذا هو السبب في أننا نرى هذا السلوك.

يمكن معالجة هذا السلوك بالذات عن طريق إضافة دعم محدد ل Func<TResult>, ، ولكن للبقاء ثابتًا ، يجب أن يكون له دعم أيضًا Func<T, TResult>, Func<T1, T2, TResult>, ، إلخ كثيراً من بين هذه أنواع المندوبين (أيضًا الإجراء ، وما إلى ذلك) ، فإن هذا يعني إضافة دعم لمجموعة كاملة من الأنواع.

ولكن ماذا عن جميع الأنواع الأخرى التي تأخذ intptr في مُنشئها؟ لا يمكن أن يعرف Autofixture عنهم جميعًا ، لذلك يبدو أن هذا لا يشبه اتجاهًا قابلاً للتطبيق.

ومع ذلك ، ماذا استطاع هل هو الحارس الذي يمنعه من محاولة إنشاء مثيلات Intptr في المقام الأول. من المرجح أن يضاف هذا قبل 2.0 RTW.

شكرا على الإبلاغ.

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