zoukankan      html  css  js  c++  java
  • 使用Moq修改默认的ASP.NET MVC项目单元测试

         当你创建一个ASP.NET MVC项目时,你可能注意到自动增加基于ASP.NET membership的名为AccountController验证类.有一个问题,当你去看AccountController单元测试类时,你会发现它们是手动Mock的类.我们可以使用第三方mocking类库来代替它们.这里使用是Moq.Moq是一个轻量级mocking框架,基于.net Framework3.5与 LINQ.它可以通过lambdas表达式来定义所期望返回值,易读的语法,待会儿看下面代码.
        首先,去Moq's Google Code 主页,下载类库,然后引用到测试项目中.用下面的代码直接替换原来的GetAccountController()方法:

    /// <summary>
    /// Gets the account controller.
    /// </summary>
    /// <returns>AccountController</returns>
    private static AccountController GetAccountController()
    {
        var mockFormsAuth = new Mock<IFormsAuthentication>();
        var mockUser = new Mock<MembershipUser>();
        mockUser.Setup(u => u.ChangePassword(It.IsAny<string>(),
            It.Is<string>(s => s == "newPass"))).Returns(true);
        var mockMembership = new Mock<MembershipProvider>();
        mockMembership.Setup(m => m.EnablePasswordReset).Returns(false);
        mockMembership.Setup(m => m.EnablePasswordRetrieval).Returns(false);
        mockMembership.Setup(m => m.MinRequiredNonAlphanumericCharacters).Returns(0);
        mockMembership.Setup(m => m.MinRequiredPasswordLength).Returns(6);
        mockMembership.Setup(m => m.ValidateUser(It.IsAny<string>(),
            It.Is<string>(s => s == "goodPass"))).Returns(true);
        mockMembership.Setup(m => m.GetUser(It.IsAny<string>(),
            It.IsAny<bool>())).Returns(mockUser.Object);
        // Registration success mock   
        MembershipCreateStatus goodStatus = MembershipCreateStatus.Success;
        mockMembership.Setup(m => m.CreateUser(It.Is<string>(s => s == "someUser"),
            It.Is<string>(s => s == "goodPass"),
            It.Is<String>(s => s == "email"), It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<bool>(),
            It.IsAny<object>(),
            out goodStatus)).Returns(mockUser.Object);
        // Registration failed mock (duplicate username)  
        MembershipCreateStatus dupeStatus = MembershipCreateStatus.DuplicateUserName;
        mockMembership.Setup(m => m.CreateUser(It.Is<string>(s => s == "someUser"),
            It.Is<string>(s => s == "badPass"), 
            It.Is<string>(s => s == "DuplicateUserName"), 
            It.IsAny<string>(), 
            It.IsAny<string>(), 
            It.IsAny<bool>(), 
            It.IsAny<object>(), 
            out dupeStatus)); 
        AccountMembershipService mockService = new AccountMembershipService(mockMembership.Object); 
        AccountController controller = new AccountController(mockFormsAuth.Object, mockService); 
        controller.SetFakeAuthenticatedControllerContext(); 
        return controller;
    }
    

          好了,现在你可以删除原来的那些手动的Mock类了,有一个验证构造函数的单元测试,你可以删除它或使用Moq来实现.SetFakeAuthenticatedControllerContext() 方法是来自Scott Hanselman's MvcMockHelpers,按新版moq做了些修改:

    /// <summary>
    /// Fakes the authenticated HTTP context.
    /// </summary>
    /// <remarks>Author: Petter Liu http://wintersun.cnblogs.com </remarks>
    /// <returns>HttpContextBase</returns>
    public static HttpContextBase FakeAuthenticatedHttpContext()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var user = new Mock<IPrincipal>();
        var identity = new Mock<IIdentity>();
    
        context.Setup(ctx => ctx.Request).Returns(request.Object);
        context.Setup(ctx => ctx.Response).Returns(response.Object);
        context.Setup(ctx => ctx.Session).Returns(session.Object);
        context.Setup(ctx => ctx.Server).Returns(server.Object);
        context.Setup(ctx => ctx.User).Returns(user.Object);
        user.Setup(ctx => ctx.Identity).Returns(identity.Object);
        identity.Setup(id => id.IsAuthenticated).Returns(true);
        identity.Setup(id => id.Name).Returns("test");
        return context.Object;
    }
    
    /// <summary>
    /// Sets the fake authenticated controller context.
    /// </summary>
    /// <param name="controller">The controller.</param>
    public static void SetFakeAuthenticatedControllerContext(this Controller controller)
    {
        var httpContext = FakeAuthenticatedHttpContext();
        ControllerContext context =
        new ControllerContext(
        new RequestContext(httpContext,
        new RouteData()), controller);
        controller.ControllerContext = context;
    }

        使用moq来mock代码比以前少了些,并且很简单.Moq在TDD中很实用,我相信如果你喜欢TDD,那么你也会慢慢喜欢Moq的.

    Author:Petter Liu     http://wintersun.cnblogs.com
  • 相关阅读:
    IDEA手动创建JFinal项目(404问题处理)
    php 把数字1-1亿换成汉字表述,例如 150 转成 一百五十
    模仿console自写函数打印js的对象
    每瓶啤酒2元,2个空酒瓶或4个瓶盖可换1瓶啤酒。10元最多可喝多少瓶啤酒? php
    js-Event构造函数,也许你需要
    js将金额专成每隔3位数加逗号
    js-PC版监听键盘大小写事件
    用php脚本给html中引用的js和css路径打上版本
    通过js的console优雅的将php调试信息输出
    android中加载的html获取的宽高不正确
  • 原文地址:https://www.cnblogs.com/wintersun/p/1487212.html
Copyright © 2011-2022 走看看