TypeLoadException عند محاولة الاستهزاء بـ IObjectSet باستخدام Moq

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

  •  14-11-2019
  •  | 
  •  

سؤال

لدي رمز الإعداد التالي:

MockOf<IObjectSet<Dummy>>().Setup(c => c.AddObject(dummy)).Verifiable();
MockOf<IObjectContextWrapper>().Setup(c => c.GetObjectSet<Dummy>()).Returns(MockOf<IObjectSet<Dummy>>().Object);

أين Dummy هو تعريف فئة فارغة، و dummy هو Dummy. MockOf<T>() هي ميزة إدارة وهمية في فئة أساسية، والتي تتأكد بشكل أساسي من أنه في كل مرة يتم استدعاؤها على نوع ما، فإنها تُرجع نفس المثيل الوهمي.

فشل الاختبار الذي يحتوي على رمز الإعداد هذا مع ملف TypeLoadException والرسالة التالية:

System.TypeLoadException :اكتب 'IObjectSet`1Proxy389e220f10aa4d9281d0b9e136edc1d4' من التجميع 'DynamicProxyGenAssembly2، الإصدار=0.0.0.0، الثقافة=محايد، PublicKeyToken=a621a9e7e5c32e69' يحاول تنفيذ واجهة لا يمكن الوصول إليها.

في System.Reflection.Emit.TypeBuilder.TermCreateClass (وحدة RuntimeModule، Int32 tk، نوع ObjectHandleOnStack)
في System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
في System.Reflection.Emit.TypeBuilder.CreateType()
في Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
في Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode (اكتب proxyTargetType، واجهات النوع []، خيارات ProxyGenerationOptions)
في Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (اكتب واجهة إلى Proxy، اكتب [] extraInterfacesToProxy، خيارات ProxyGenerationOptions، اعتراضات IInterceptor [])
في موك موك1.<InitializeInstance>b__0()
at Moq.Mock
1. تهيئة المثيل ()
في Moq.Mock`1.get_Object()
في OddEnds.Tests.Data.EntityFramework.RepositoryTest.Delete_DeletesObjectFromObjectSet() في RepositoryTest.cs:السطر 43

لقد استوردت System.Data.Objects وتمت الإشارة إلى كل من System.Data.Entity.dll وMicrosoft.Data.Entity.CTP.dll في كل من مشروع الاختبار والمشروع الذي توجد فيه الفئة التي يتم اختبارها.نجح البناء بدون أي أخطاء أو تحذيرات أو رسائل (باستثناء القليل منها المتعلق بعقود التعليمات البرمجية...)

كيف يمكنني حل هذه المشكلة؟

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

المحلول

هل أي من الواجهات أو الفئات التي تستخدمها في اختباراتك داخلية؟هل تستخدم شيئا مثل [assembly: InternalsVisibleTo("YourTestAssembly")] من أجل الحصول على الأشياء لتجميع؟

إذا كان الأمر كذلك، فستحتاج أيضًا إلى إضافة واحد لـ DynamicProxyGenAssembly2 حتى يتمكن Moq من إنشاء الوكيل للفئات ديناميكيًا.

//goes in the AssemblyInfo.cs where the internal interfaces / classes are defined
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]  

وهنا وظيفة ذات الصلة حول هذا الموضوع

http://sonofpirate.blogspot.com/2009/09/my-first-foray-into-unit-testing-with.html

آمل أن يساعد هذا

نصائح أخرى

لقد وجدت أنه في حالتي قمت بإنشاء مثيل فئة وهمية لاستخدامه في اختبار الوحدة الخاص بي والذي كان خاصًا (لأنني لم أرغب حقًا في مشاركة كائن الاختبار في الخارج).

كان الكود الخاص بي على هذا المنوال:

var mockMonitor = new Mock<ICacheMonitor<int, PrivateObject>>();

حيث كان PrivateObject عبارة عن تعريف فئة خاصة ضمن TestClass الخاص بي.وبالتالي فإن الإصلاح في حالتي هو التأكد من أن أيًا من الأنواع الموجودة في مُنشئ Mock الخاص بك عامة.

public class PrivateObject () {}

(من الواضح أنني لن أسمي كائني العام كائنًا خاصًا أيضًا ...)

لقد تعثرت في حالة أخرى لم أتمكن من اكتشافها في البداية.كنت أعمل على وكيل لواجهة تم إنشاؤها داخل اختبار الوحدة الخاص بي ...

public IDoWork
{
    void DoWork();
}

لقد استغرق الأمر وقتًا طويلاً لأكتشف أن المشكلة لم تكن في تلك الواجهة، بل كانت في أن اختبار الوحدة نفسه لم يكن عامًا:

class TestSomething // missing public keyword
{

// .. some test which tries to create a mock of the interface


    public IDoWork
    {
        void DoWork();
    }

}

لذلك، في حين أن IDoWork يقول إنه عام، فهو في الحقيقة ليس كذلك لأنه محاط بفئة خاصة.

أمل أن هذا يساعد شخصاما.

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