سؤال

أنا في محاولة لمعرفة اختبار وحدة.أنا أحاول أن وحدة اختبار بعض Memembership الأشياء أنا صنع في asp.net mvc 1.0.أنا أتابع كتاب على MVC و أنا في حيرة حول بعض الأشياء التي نأمل شخص ما يمكن أن تصل واضحة بالنسبة لي.

أنا باستخدام Nunit و موك لبلدي الأطر.

السؤال 1:

  public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider provider)
        {
            FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
            Provider = provider ?? Membership.Provider;
        }

أنا مشوش ما "??" لا أنا لم أر ذلك من قبل.مثل أنا لا أعرف حتى ما يحدث حقا هنا.مثل ما يفعلها واجهة ثم "??" مارك يحدث ويجعل جديد FormsAuthenticationWraper ؟

السؤال 2.

 public AuthenticationController(): this(null, null)
        {
        }

أعرف أن هذا هو منشئ افتراضي ولكن أنا لست متأكدا من السبب ":هذا(null,null)" يفعل.

مثل ما هو تنفيذ?و ما هو هذا يشير أيضا.وعلى أعلى من ذلك لماذا لا يمكن أن يكون مجرد ترك ؟ و مجرد عصا منشئ افتراضي كما هو.

السؤال 3.

في كتاب(asp.net mvc 1.0 بسرعة) يتحدث عن كيف سيكون قليلا جدا من العمل على تنفيذ Memembership مزود سيكون الكثير من العمل.حتى أنها تستخدم موك بالحجم الطبيعي إطار لجعل الحياة أسهل.

الآن سؤالي هو أنها لا تستخدم موك على "FormsAuthentication".أنهم بدلا من ذلك جعل واجهة

   public interface IFormsAuthentication
        {
            void SetAuthCookie(string userName, bool createPersistentCookie);
            void SignOut();


        }

ثم جعل المجمع

الطبقة العامة FormsAuthenticationWrapper :IFormsAuthentication { الفراغ العام SetAuthCookie(سلسلة اسم المستخدم منطقي createPersistentCookie) { FormsAuthentication.SetAuthCookie(اسم المستخدم ، createPersistentCookie);} الفراغ العام آثارها() { FormsAuthentication.سينوت();}

}

ثم أخيرا عقار

   public IFormsAuthentication FormsAuth
        {
            get;
            private set;
        }

حيث كما هو الحال مع عضوية لديهم فقط

الجمهور ثابت MembershipProvider مزود { الحصول ؛ مجموعة الخاص ؛ }

أنا لست متأكدا رغم ما إلى تغيير الأشياء أيضا.مثل ما أود أن تغيير هذا الخط أيضا ؟

FormsAuth = formsAuth ??جديد FormsAuthenticationWrapper();

كما أنني حاولت أن أضيف طريقة أخرى في FormsAuthentication واجهة المجمع.

الفراغ العام RedirectFromLoginPage(سلسلة اسم المستخدم منطقي createPersistentCookie) { FormsAuthentication.RedirectFromLoginPage(اسم المستخدم ، createPersistentCookie);}

حتى الآن أنا غير متأكد ما يحدث ولكن وحدتي اختبار تفشل دائما لا يهم ما أحاول القيام به لاصلاحها.

     public ActionResult Login(string returnUrl, FormCollection form, bool rememberMe)
            {
                LoginValidation loginValidation = new LoginValidation();
                try
                {
                    UpdateModel(loginValidation, form.ToValueProvider());

                }
                catch
                {

                    return View("Login");
                }

                if (ModelState.IsValid == true)
                {

                    bool valid = authenticate.VerifyUser(loginValidation.UserName, loginValidation.Password);

                    if (valid == false)
                    {
                        ModelState.AddModelError("frm_Login", "Either the Password or UserName is invalid");

                    }
                    else if (string.IsNullOrEmpty(returnUrl) == false)
                    {
                        /* if the user has been sent away from a page that requires them to login and they do 
                         * login then redirect them back to this area*/
                        return Redirect(returnUrl);
                    }
                    else
                    {

                       FormsAuth.RedirectFromLoginPage(loginValidation.UserName, rememberMe);
                    }

                }


                return View("Login");


Here is my test

[اختبار] الفراغ العام Test_If_User_Is_Redirected_Back_to_page_they_came_from_after_login() { النظام.تشخيص.المصحح.كسر();

       var formsAuthenticationMock =  new Mock<AuthenticationController.IFormsAuthentication>();

       var membershipMock = new Mock<MembershipProvider>();

       membershipMock.Setup(m => m.ValidateUser("chobo2", "1234567")).Returns(true);


       // Setup controller
       AuthenticationController target = new AuthenticationController(formsAuthenticationMock.Object, membershipMock.Object);


       // Execute
       FormCollection form = new FormCollection();
       form.Add("Username", "chobo2");
       form.Add("password", "1234567");

       ViewResult actual = target.Login(null, form, false) as ViewResult;

       Assert.That(actual.View, Is.EqualTo("home"));
       formsAuthenticationMock.Verify();

   }

الفعلية تأتي دائما العودة إلى null.حاولت ViewResult, RedirectResult و RedirectToRouteResult ولكن الجميع يعود null.لذلك أنا لست متأكدا لماذا يحدث هذا منذ أجد أنه من الغريب الأولى التي

                       FormsAuth.RedirectFromLoginPage(loginValidation.UserName, rememberMe);

لا يوقف عرض ويبدأ في إعادة توجيه.ظننت في البداية عندما يضرب هذا الخط هو مثل العودة بيان هذا الأمر أي رمز آخر سيتم تنفيذه ولكن htis لا يبدو أن القضية لذلك أنا لست متأكدا إذا كان هذا يمكن أن يكون مشكلة.

شكرا

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

المحلول

السؤال 1

على ?? ويسمى null-ائتلافه المشغل, و هي ميزة مفيدة جدا من C# 2.0 وما بعدها.

في الحالة الخاصة بك ،

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

يعني ببساطة "تعيين formsAuth إلى FormsAuth إلا أنه باطل ، في هذه الحالة تعيين new FormsAuthenticationWrapper()".انها في الأساس وسيلة منع null المراجع في التعليمات البرمجية الخاصة بك.يمكنك أيضا أن نفكر في الأمر على النحو المختصرة التالية التعبير الشرطي:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

السؤال 2

استخدام this(null, null) ويسمى منشئ تسلسل.كل هذا يعني أن منشئ في نفس الفئة (ومن هنا this, مقابل base عن فئة الأم) أن يأخذ اثنين المعلمات ، ينبغي أن تسمى قبل هيئة منشئ يتم تنفيذها.

الحمولة الزائدة منشئات هو ممارسة شائعة يسهل على المطور لإنشاء كائنات جديدة عندما ترغب فقط في استخدام الخصائص الافتراضية/إعدادات.

السؤال 3

كما ذكر آخرون أن هذا حقا ينتمي منفصلة السؤال.على عكس السابقتين ، إنها أكثر من ذلك بكثير خاصة السياق/التعليمات البرمجية الخاصة بك بدلا من ميزات اللغة C#.

التحديث

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

public AuthenticationController()
    : this(new FormsAuthenticationWrapper(), Membership.Provider)
{
}

public AuthenticationController(IFormsAuthentication formsAuth,
    MembershipProvider provider)
{
    this.FormsAuth = formsAuth;
    this.Provider = provider;
}

في هذا النموذج ، ينبغي أن يكون من الواضح أن منشئ أن يأخذ اثنين المعلمات ببساطة يعين الطبقة المتغيرات قيم الحجج.على parameterless منشئ (غالبا ما تسمى الافتراضي منشئ) ببساطة بإنشاء كائن جديد باستخدام الافتراضي FormsAuth و Provider الكائنات التي تم تحديدها عن طريق منشئ تسلسل.

نصائح أخرى

والسؤال 1: ؟؟ هو في اغية مشغل التحام . ال ؟؟ الشيكات المشغل ما إذا كانت القيمة المقدمة على الجانب الأيسر من التعبير فارغة، وإذا كان الأمر كذلك تقوم بإرجاع قيمة بديلة أشار الجانب الأيمن من التعبير.

في الوضع الخاص بك، فإنه يتحقق إذا formsAuth لاغيا، وإرجاع FormsAuthenticationWrapper الجديدة () إذا كانت فارغة.

وو؟؟ مشغل يقول "استخدام هذا، إلا إذا كان لاغيا، وهذه الحالة استخدام هذا الشيء الآخر".

وهكذا، وهذا سطر من التعليمات البرمجية:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

وهو نفسه على النحو التالي:

if ( formsAuth != null ) FormsAuth = formsAuth
else FormsAuth = new FormsAuthenticationWrapper();

في الإجابة على Q2

ومن إثقال المنشئ.

إذا يعني أن الدعوة

Foo() 

وهو نفس الدعوة

Foo(null, null)

السؤال 1: على ?? المشغل ببساطة تقول "خذ ما هو على يساري إذا لم تكن فارغة - إذا كان هو أخذ ما هو على الحق".لذلك الرمز الخاص بك:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

ما يعادل

if (formsAuth != null) {
    FormsAuth = formsAuth;
} else {
    FormsAuth 0 new FormsAuthenticationWrapper();
}

السؤال 2: على :this(null, null) بناء الجملة هو اختصار ل "منشئ الميراث" (بلدي تسمية...).التعليمات البرمجية الخاصة بك

public AuthenticationController(): this(null, null)
    {
    }
public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider  provider)
    {
        FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
        Provider = provider ?? Membership.Provider;
    }

ما يعادل

public AuthenticationController()
    {
        FormsAuth = new FormsAuthenticationWrapper();
        Provider = Membership.Provider;
    }
public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider provider)
    {
        FormsAuth = formsAuth;
        Provider = provider;
    }

السؤال 2

public AuthenticationController(): this(null, null)
{
}

لا المعلمة منشئ AuthenticationController سيتم استدعاء منشئ أن يأخذ IFormsAuthentication و MembershipProvider ، ويمر اثنين القيم الخالية (يتم ذلك قبل أي قانون في أي بارام منشئ التعليمات البرمجية يتم تنفيذ كتلة).منذ اثنين حجة منشئ يستخدم null-ائتلافه (??) مشغل تعيين المتغيرات مرت حجج فارغة, جديد MembershipProvider يستخدم جنبا إلى جنب مع الأعضاء.مزود الكائن.

كان هذا المنشئ تكن واضحة ، الافتراضي لا بارام منشئ قد استخدمت.هذا يمكن أن يؤدي إلى سلوك غير متوقع إذا كان جديد AuthenticationController تم إنشاء (دون تمرير أي حجج المنشئ) ، منذ الأعضاء المتغيرات قد تم تفعيلها

والسؤال 1:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Provider = provider ?? Membership.Provider;

وهو يساوي:

FormsAuth = (formsAuth == null ? new FormsAuthenticationWrapper() : formsAuth);
Provider = (provider == null ? Membership.Provider : provider);

والسؤال 2:

وانها مجرد مرور فارغة إلى كل من formsAuth والحجج مزود المنشئ. انها ليست جيدة IMHO الممارسة. أن منشئ آخر بدون وسائط أن يكون لائقا أفضل.

تعديل : هذا لا معنى له. آسف، كنت في عجلة من امرنا، ولم ندرك حقا كان منشئ الدعوة منشئ آخر.

وليس لدي الوقت للإجابة على السؤال 3 في الوقت الراهن، وسوف نصل الى ذلك في وقت لاحق ...

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