需要帮助了解此代码 [英] Need Help understanding this code

查看:111
本文介绍了需要帮助了解此代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习单元测试.我正在尝试对我在asp.net mvc 1.0中制作的Memembership内容进行单元测试.我一直在关注有关MVC的书,但对某些东西感到困惑,希望有人可以帮我清理一下.

I am trying to learn unit testing. I am trying to unit test some Memembership stuff I am making in asp.net mvc 1.0. I been following a book on MVC and I am confused about some stuff that hopefully someone can clear up for me.

我正在将Nunit和Moq用于我的框架.

I am using Nunit and Moq for my frameworks.

问题1:

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

我有点困惑"我以前从未真正看过它吗?就像我什至不知道这里到底发生了什么.就像他们传入接口,然后是"??"标记发生并制作了新的FormsAuthenticationWraper?

I am kinda confused what "??" does I never really seen it before. Like I don't even know whats happening really in here. Like they passin the interface and then "??" mark happens and makes a new FormsAuthenticationWraper is made?

问题2.

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

我知道这是默认的构造函数,但是我不确定为什么:this(null,null)"在执行.

I know this is the default constructor but I am not sure why ": this(null,null)" is doing.

像它正在执行什么?这也指的是什么.最重要的是,为什么不能仅仅将其排除在外呢?只需保留默认构造函数即可.

Like what is it implementing? and what is this refering too. And on top of it why can't that be just left out? And just stick the default constructor as it is.

问题3.

在书中(asp.net mvc 1.0很快),它讨论了实现Memembership提供程序要花很多工作.因此他们使用moq样机框架来简化生活.

In the book(asp.net mvc 1.0 quickly) it talks about how it would be quite a bit of work to implementing the Memembership provider would be alot of work. So they use moq mockup framework to make life easier.

现在我的问题是,他们不使用"FormsAuthentication"上的最小起订量.他们创建了一个界面

Now my question is they don't use the moq on the "FormsAuthentication". They instead make an interface

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


        }

然后做一个包装纸

公共类FormsAuthenticationWrapper:IFormsAuthentication { 公共无效SetAuthCookie(字符串userName,布尔createPersistentCookie) { FormsAuthentication.SetAuthCookie(userName,createPersistentCookie); } 公共无效SignOut() { FormsAuthentication.SignOut(); }

public class FormsAuthenticationWrapper : IFormsAuthentication { public void SetAuthCookie(string userName, bool createPersistentCookie) { FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); } public void SignOut() { FormsAuthentication.SignOut(); }

}

然后是一个属性

   public IFormsAuthentication FormsAuth
        {
            get;
            private set;
        }

与成员资格相同的地方

公共静态MembershipProvider提供程序 { 得到; 私人套装; }

public static MembershipProvider Provider { get; private set; }

我也不知道该怎么改变.就像我也会改变这条线吗?

I am not sure though what to change the stuff too. Like what would I change this line too?

FormsAuth = FormsAuth ??新的FormsAuthenticationWrapper();

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

我还试图将其他方法添加到FormsAuthentication Interface and Wrapper中.

I also tried to add another method into the FormsAuthentication Interface and Wrapper.

public void RedirectFromLoginPage(字符串userName,布尔型createPersistentCookie) { FormsAuthentication.RedirectFromLoginPage(userName,createPersistentCookie); }

public void RedirectFromLoginPage(string userName, bool createPersistentCookie) { FormsAuthentication.RedirectFromLoginPage(userName, createPersistentCookie); }

但是我不确定发生了什么,但是我的单元测试始终失败,无论我尝试如何修复它都无所谓.

Yet I am not sure what is happening but my unit test always fails does not matter what I try to do to fix it.

     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_他们_Came_From_After_Login() { System.Diagnostics.Debugger.Break();

[Test] public void Test_If_User_Is_Redirected_Back_To_Page_They_Came_From_After_Login() { System.Diagnostics.Debugger.Break();

       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();

   }

Actual总是返回null.我尝试了ViewResult,RedirectResult和RedirectToRouteResult,但是每个人都返回null.所以我不确定为什么会这样,因为我首先觉得

Actual always comes back to null. I tried ViewResult, RedirectResult and RedirectToRouteResult but everyone comes back null. So I am not sure why this is happening since I find it weird first that

                       FormsAuth.RedirectFromLoginPage(loginValidation.UserName, rememberMe);

不停止视图并开始重定向.我以为一开始它就像这条返回语句一样,那就是没有其他代码将被执行,但是htis似乎不是这种情况,所以我不确定这是否是问题所在.

Does not stop the view and starts to redirect. I thought at first once it hits this line it is like a return statement and thats it no other code will be executed but htis does not seem to be the case so I am not sure if this could be the problem.

谢谢

推荐答案

问题1

??被称为 空伙伴运算符 ,并且是C#2.0及更高版本中非常有用的功能.

Question 1

The ?? is called the null-coalescing operator, and is a very useful feature of C# 2.0 onwards.

就您而言,

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

的简单含义是将formsAuth分配给FormsAuth,除非它为空,在这种情况下,分配new FormsAuthenticationWrapper()".基本上,这是一种防止代码中出现空引用的方法.您也可以将其视为以下条件表达式的快捷方式:

simply means "assign formsAuth to FormsAuth unless it is null, in which case assign new FormsAuthenticationWrapper()". It's basically a way of preventing null references in your code. You can also think of it as a shortcut for the following conditional expression:

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

问题2

this(null, null)的使用称为 构造函数链接 .这意味着在执行构造函数的主体之前,应调用具有两个参数的同一个类(因此,父类为this,而不是base)中的构造函数.

Question 2

The use of this(null, null) is called constructor chaining. All this means is that that the constructor in the same class (hence this, as opposed to base for the parent class) that takes two parameters, should be called before the body of the constructor is executed.

重载构造函数是一种常见做法,可以使开发人员在只想使用默认属性/设置的情况下更轻松地创建新对象.

Overloading constructors is a common practice to make it easier for the developer to create new objects when they just want to use the default properties/settings.

正如其他人提到的那样,这确实是一个单独的问题.与前两者不同,它更特定于上下文/您的代码,而不是C#的语言功能.

As others have mentioned, this really belongs as a separate question. Unlike the previous two, it's much more specific to the context/your code, rather than language features of C#.

好吧,我现在所做的实际上实际上是在这里重写了两个构造函数,因为我认为将它们以另一种(实际上等效)的形式放置可能会更清晰一些,并且可能也是更好的设计实践.这里不需要null合并运算符.

Ok, what I've done now is actually rewritten the two constructors here, since I think putting them in another (virtually equivalent) form might be a bit clearer, and is probably better design practice too. The null coalescing operator isn't necessary here.

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

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

以这种形式,很明显,采用两个参数的构造函数只是将类变量分配给参数的值.无参数构造函数(通常称为 default 构造函数)仅使用 default FormsAuthProvider对象创建新对象,这些对象是通过 constructor链指定的.

In this form, it should be obvious that the constructor that takes two parameters simply assigns the class variables to the values of the arguments. The parameterless constructor (often called the default constructor) simply creates a new object using the default FormsAuth and Provider objects, which are specified via constructor chaining.

这篇关于需要帮助了解此代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆