رينوموكس:الطريقة الصحيحة للسخرية من الملكية

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

  •  09-06-2019
  •  | 
  •  

سؤال

أنا جديد على RhinoMocks، وأحاول التعرف على بناء الجملة بالإضافة إلى ما يحدث تحت الغطاء.

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

وهذا ما أفعله حتى الآن:

public void CreateSomethingIfUserHasAdminPermissions()
{
    User user = _mocks.StrictMock<User>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
} 

الآن، أتوقع أن يقوم Rhino "بتزييف" المكالمة إلى صاحب الملكية، ويعود لي صادقًا.هل هذا غير صحيح؟أتلقى حاليًا استثناءً بسبب التبعيات في خاصية IsAdministrator.

هل يمكن لأحد أن يشرح كيف يمكنني تحقيق هدفي هنا؟

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

المحلول

ملاحظة سريعة واحدة قبل أن أقفز إلى هذا.عادةً ما تريد تجنب استخدام النموذج "الصارم" لأنه يجعل الاختبار هشًا.ستطرح المحاكاة الصارمة استثناءً في حالة حدوث أي شيء لم تخبره صراحةً بأن Rhino سيحدث.أعتقد أيضًا أنك قد تسيء فهم ما يفعله Rhino بالضبط عندما تجري مكالمة لإنشاء نموذج وهمي.فكر في الأمر ككائن مخصص تم اشتقاقه من System.Type الذي حددته أو تنفيذه.إذا قمت بذلك بنفسك فسيبدو الأمر كما يلي:

public class FakeUserType: User
{
    //overriding code here
}

نظرًا لأن IsAdministrator ربما يكون مجرد خاصية عامة من نوع المستخدم، فلا يمكنك تجاوزها في النوع الموروث.

بقدر ما يتعلق الأمر بسؤالك، هناك طرق متعددة يمكنك من خلالها التعامل مع هذا الأمر.يمكنك تطبيق IsAdministrator كخاصية افتراضية على فئة المستخدم الخاصة بك aaronjensen المذكورة على النحو التالي:

public class User
{
    public virtual Boolean IsAdministrator { get; set; }
}

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

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

public interface IUser
{
    Boolean IsAdministrator { get; }
}

public class User : IUser
{
    private UserSecurity _userSecurity = new UserSecurity();

    public Boolean IsAdministrator
    {
        get { return _userSecurity.HasAccess("AdminPermissions"); }
    }
}

public void CreateSomethingIfUserHasAdminPermissions()
{
    IUser user = _mocks.StrictMock<IUser>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
}

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

آمل أن يساعد هذا.لقد كنت أستخدم RhinoMocks لفترة طويلة في مشروع كبير الآن، لذا لا تتردد في طرح أسئلة حول TDD والاستهزاء بي.

نصائح أخرى

تأكد من أن IsAdministrator افتراضي.

تأكد أيضًا من الاتصال بـ _mocks.ReplayAll()

_mocks.ReplayAll() لن تفعل شيئًا.هذا فقط لأنك تستخدم SetupResult.For() لا يتم احتسابه.استخدم Accept.Call() للتأكد من أن التعليمات البرمجية الخاصة بك تفعل كل شيء بشكل صحيح.

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