الاستهزاء User.Identity في ASP.NET MVC



asp.net-mvc mocking (4)

لا أعرف بالنسبة لـ MVC 2.0 ، ولكن في الإصدارات الأحدث ، يمكنك الاستهزاء بـ ControllerContext:

// create mock principal
var mocks = new MockRepository(MockBehavior.Default);
Mock<IPrincipal> mockPrincipal = mocks.Create<IPrincipal>();
mockPrincipal.SetupGet(p => p.Identity.Name).Returns(userName);
mockPrincipal.Setup(p => p.IsInRole("User")).Returns(true);

// create mock controller context
var mockContext = new Mock<ControllerContext>();
mockContext.SetupGet(p => p.HttpContext.User).Returns(mockPrincipal.Object);
mockContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

// create controller
var controller = new MvcController() { ControllerContext = mock.Object };

راجع أيضًا كيفية اختبار إجراء تحكم وحدة MVC الذي يعتمد على التوثيق في c #؟

https://src-bin.com

أحتاج إلى إنشاء "اختبارات الوحدات" لموقع ويب ASP.NET MVC 2.0. يستخدم الموقع مصادقة Windows.

لقد قرأت عن الحاجة للسخرية من سياق HTTP للكود الذي يتعامل مع HttpContext. أشعر أنني بدأت في الحصول على مؤشر على نمط DI أيضًا. (أعط الفئة سمة من سمات IRepository ، ثم قم بتمريرها في كائن السجل عند إنشاء مثيل لوحدة التحكم.)

ومع ذلك ، فإن ما لا أفهمه هو الطريقة الصحيحة للسخر من كائن Windows الرئيسي المتاح من خلال User.Identity. هل هذا جزء من HttpContext؟

هل لدى أي جهة رابط لمقال يوضح هذا (أو توصية لكتاب)؟

شكر،

تري كارول


Answer #1

لقد استخدمت IoC لاستخراج هذا مع بعض النجاح. قمت أولاً بتحديد فئة لتمثيل المستخدم الذي قام بتسجيل الدخول حاليًا:

public class CurrentUser
{
    public CurrentUser(IIdentity identity)
    {
        IsAuthenticated = identity.IsAuthenticated;
        DisplayName = identity.Name;

        var formsIdentity = identity as FormsIdentity;

        if (formsIdentity != null)
        {
            UserID = int.Parse(formsIdentity.Ticket.UserData);
        }
    }

    public string DisplayName { get; private set; }
    public bool IsAuthenticated { get; private set; }
    public int UserID { get; private set; }
}

يستغرق IIdentity في المنشئ لتعيين قيمه. بالنسبة لاختبارات الوحدات ، يمكنك إضافة مُنشئ آخر للسماح لك بتجاوز تبعية IIdentity .

ثم أستخدم Ninject (اختر حاوية IoC المفضلة لديك ، لا يهم) ، وقمت بإنشاء رابط لـ IIdentity على هذا النحو:

Bind<IIdentity>().ToMethod(c => HttpContext.Current.User.Identity);

ثم ، داخل وحدة التحكم الخاصة بي ، أعلن التبعية في المُنشئ:

CurrentUser _currentUser;

public HomeController(CurrentUser currentUser)
{
    _currentUser = currentUser;
}

ترى حاوية HomeController أن HomeController يأخذ كائن CurrentUser ، ويأخذ مُنشئ CurrentUser IIdentity . وسوف يحل التبعيات تلقائيا ، وفويلا! يمكن لوحدة التحكم الخاصة بك معرفة هوية المستخدم الذي قام بتسجيل الدخول حاليًا. يبدو أن تعمل بشكل جيد بالنسبة لي مع FormsAuthentication. قد تتمكن من تكييف هذا المثال مع مصادقة Windows.


Answer #2

للسخرية من WindowsIdentity يمكنك القيام بما يلي:

var mockedPrincipal = new Mock<WindowsPrincipal>(WindowsIdentity.GetCurrent());

mockedPrincipal.SetupGet(x => x.Identity.IsAuthenticated).Returns(true);
mockedPrincipal.SetupGet(x => x.Identity.Name).Returns("Domain\\User1");
mockedPrincipal.Setup(x => x.IsInRole("Domain\\Group1")).Returns(true);
mockedPrincipal.Setup(x => x.IsInRole("Domain\\Group2")).Returns(false);

ثم استخدم mockedPrincipal.Object للحصول على WindowsIdentity الفعلي


Answer #3

يوضح Scott Hanselman في مدونته كيفية استخدام IPrincipal و ModelBinder لتسهيل اختبار وحدة التحكم عن طريق الاستهزاء IPrincipal.





mocking