• 使用Fakes的Stub和Shim对ASP.NET MVC4进行单元测试


    这是一篇导航文,不是翻译。

    MSDN对stub和shim的解释和使用场景演示:http://msdn.microsoft.com/en-us/library/hh549175.aspx
    一个更详细的示例:http://www.richonsoftware.com/post/2012/04/05/Using-Stubs-and-Shim-to-Test-with-Microsoft-Fakes-in-Visual-Studio-11.aspx

    我感兴趣的是如何对mvc项目进行测试:http://www.richonsoftware.com/post/2012/05/02/Noninvasive-Unit-Testing-in-ASPNET-MVC-A-Microsoft-Fakes-Deep-Dive.aspx
    里面讲的内容分别有:

    1,利用shim来重写第三方类库或系统类库的方法

    [TestMethod]
    public void TestLogOff()
    {
        var accountController = new AccountController();
        var formsAuthenticationSignOutCalled = false;
        RedirectToRouteResult redirectToRouteResult;
     
        //Scope the detours we're creating
        using (ShimsContext.Create())
        {
            //Detours FormsAuthentication.SignOut() to an empty implementation
            ShimFormsAuthentication.SignOut = () =>
            {
                //Set a boolean to identify that we actually got here
                formsAuthenticationSignOutCalled = true;
            };
            redirectToRouteResult = accountController.LogOff() as RedirectToRouteResult;
            Assert.AreEqual(true, formsAuthenticationSignOutCalled);
        }
     
        Assert.NotNull(redirectToRouteResult);
        Assert.AreEqual("Index", redirectToRouteResult.RouteValues["Action"]);
        Assert.AreEqual("Home", redirectToRouteResult.RouteValues["controller"]);
    }
    

    2,怎么判断该用stub


    [TestMethod]
    public void TestLogin()
    {
        string testUserName = "TestUserName";
        string testPassword = "TestPassword";
        bool testRememberMe = false;
        string returnUrl = "/foo.html";
     
        var loginModel = new LoginModel
        {
            UserName = testUserName,
            Password = testPassword,
            RememberMe = testRememberMe
        };
     
        var accountController = new AccountController();
     
        //Setup underpinning via stubbing such that UrlHelper 
        //can validate that our "foo.html" is local
        var stubHttpContext = new StubHttpContextBase();
        var stubHttpRequestBase = new StubHttpRequestBase();
        stubHttpContext.RequestGet = () => stubHttpRequestBase;
        var requestContext = new RequestContext(stubHttpContext, new RouteData());
        accountController.Url = new UrlHelper(requestContext);
     
        RedirectResult redirectResult;
        //Scope the detours we're creating
        using (ShimsContext.Create())
        {
            //Sets up a detour for Membership.ValidateUser to our mocked implementation
            ShimMembership.ValidateUserStringString = (userName, password) =>
            {
                Assert.AreEqual(testUserName, userName);
                Assert.AreEqual(testPassword, password);
                return true;
            };
     
            //Sets up a detour for FormsAuthentication.SetAuthCookie to our mocked implementation
            ShimFormsAuthentication.SetAuthCookieStringBoolean = (userName, rememberMe) =>
            {
                Assert.AreEqual(testUserName, userName);
                Assert.AreEqual(testRememberMe, rememberMe);
            };
     
            redirectResult = accountController.Login(loginModel, returnUrl) as RedirectResult;
        }
     
        Assert.NotNull(redirectResult);
        Assert.AreEqual(redirectResult.Url, returnUrl);
    }

    3,如何还原动态对象


    [TestMethod]
    public void TestInvalidJsonLogin()
    {
        string testUserName = "TestUserName";
        string testPassword = "TestPassword";
        bool testRememberMe = false;
        string testReturnUrl = "TestReturnUrl";
     
        var loginModel = new LoginModel
        {
            UserName = testUserName,
            Password = testPassword,
            RememberMe = testRememberMe
        };
     
        var accountController = new AccountController();
        JsonResult jsonResult;
        //Scope the detours we're creating
        using (ShimsContext.Create())
        {
            //Sets up a detour for Membership.ValidateUser to our mocked implementation
            ShimMembership.ValidateUserStringString = (userName, password) => false;
            jsonResult = accountController.JsonLogin(loginModel, testReturnUrl);
        }
         //答案在这里
        var errors = (IEnumerable<string>)(new PrivateObject(jsonResult.Data, "errors")).Target;
        Assert.AreEqual("The user name or password provided is incorrect.", errors.First());
    

    4,如何给请求添加上下文,及如何在请求中加入用户对象


    [TestMethod]
    public void TestChangePassword()
    {
        string testUserName = "TestUserName";
        string testOldPassword = "TestOldPassword";
        string testNewPassword = "TestNewPassword";
     
        var changePasswordModel = new ChangePasswordModel
        {
            OldPassword = testOldPassword,
            NewPassword = testNewPassword
        };
     
        var accountController = new AccountController();
     
        //Stub HttpContext
        var stubHttpContext = new StubHttpContextBase();
        //Setup ControllerContext so AccountController will use our stubHttpContext
        accountController.ControllerContext = new ControllerContext(stubHttpContext, 
            new RouteData(), accountController);
     
        //Stub IPrincipal
        var principal = new StubIPrincipal();
        principal.IdentityGet = () =>
        {
            var identity = new StubIIdentity { NameGet = () => testUserName };
            return identity;
        };
        stubHttpContext.UserGet = () => principal;
     
        RedirectToRouteResult redirectToRouteResult;
        //Scope the detours we're creating
        using (ShimsContext.Create())
        {
            ShimMembership.GetUserStringBoolean = (identityName, userIsOnline) =>
            {
                Assert.AreEqual(testUserName, identityName);
                Assert.AreEqual(true, userIsOnline);
     
                var memberShipUser = new ShimMembershipUser();
                //Sets up a detour for MemberShipUser.ChangePassword to our mocked implementation
                memberShipUser.ChangePasswordStringString = (oldPassword, newPassword) =>
                {
                    Assert.AreEqual(testOldPassword, oldPassword);
                    Assert.AreEqual(testNewPassword, newPassword);
                    return true;
                };
                return memberShipUser;
            };
     
            var actionResult = accountController.ChangePassword(changePasswordModel);
            Assert.IsInstanceOf(typeof(RedirectToRouteResult), actionResult);
            redirectToRouteResult = actionResult as RedirectToRouteResult;
        }
        Assert.NotNull(redirectToRouteResult);
        Assert.AreEqual("ChangePasswordSuccess", redirectToRouteResult.RouteValues["Action"]);
    } 
       
    上面种种,文章给的不仅仅是答案,更有思考过程,比如问题原因,可能的解决方法,以及最后给一个最优的方法,值得一读的。

  • 相关阅读:
    asp.net 数据导出到Excel
    系统架构之畅想
    access2003绿色中文版(转)
    项目那点事(共享)
    不错的消息提示
    配置Windows media service 流媒体服务器
    MemberShip 数据库的安装,web.config的配置及数据库文档结构
    windows server 2003 service pack 2 无法安装...产品密钥可能无效
    残忍,人
    js小技巧鼠标滑过显示大图
  • 原文地址:https://www.cnblogs.com/walkerwang/p/3357692.html
Copyright © 2020-2023  润新知