代码之家  ›  专栏  ›  技术社区  ›  Codewerks

ASP/NET MVC:是否使用会话测试控制器?嘲笑?

  •  43
  • Codewerks  · 技术社区  · 16 年前

    我在这里读了一些答案:测试视图和控制器,以及模拟,但我仍然不知道如何测试一个读取和设置会话值(或任何其他基于上下文的变量)的ASP.NET MVC控制器 如何为测试方法提供(会话)上下文?嘲笑就是答案吗?有人举过例子吗? 基本上,我想在调用controller方法并让controller使用该会话之前伪造一个会话。有什么想法吗?

    7 回复  |  直到 16 年前
        1
  •  44
  •   Patrick McDonald    14 年前

    查看Stephen Walther关于伪造控制器上下文的帖子:

    ASP.NET MVC Tip #12 – Faking the Controller Context

    [TestMethod]
    public void TestSessionState()
    {
        // Create controller
        var controller = new HomeController();
    
    
        // Create fake Controller Context
        var sessionItems = new SessionStateItemCollection();
        sessionItems["item1"] = "wow!";
        controller.ControllerContext = new FakeControllerContext(controller, sessionItems);
        var result = controller.TestSession() as ViewResult;
    
    
        // Assert
        Assert.AreEqual("wow!", result.ViewData["item1"]);
    
        // Assert
        Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]);
    }
    
        2
  •  14
  •   chadmyers    16 年前

    例如,下面是我们如何管理表单auth的内容。我们有一个ISecurityContext:

    public interface ISecurityContext
    {
        bool IsAuthenticated { get; }
        IIdentity CurrentIdentity { get; }
        IPrincipal CurrentUser { get; set; }
    }
    

    具体实现如下:

    public class SecurityContext : ISecurityContext
    {
        private readonly HttpContext _context;
    
        public SecurityContext()
        {
            _context = HttpContext.Current;
        }
    
        public bool IsAuthenticated
        {
            get { return _context.Request.IsAuthenticated; }
        }
    
        public IIdentity CurrentIdentity
        {
            get { return _context.User.Identity; }
        }
    
        public IPrincipal CurrentUser
        {
            get { return _context.User; }
            set { _context.User = value; }
        }
    }
    
        3
  •  10
  •   keparo    15 年前

    var controller = new HomeController();
    var context = MockRepository.GenerateStub<ControllerContext>();
    context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue");
    controller.ControllerContext = context;
    

    看见 Scott Gu's post 更多细节。

        4
  •  5
  •   Korbin    16 年前

    我发现嘲弄是相当容易的。下面是一个使用moq模拟httpContextbase(包含请求、会话和响应对象)的示例。

    [TestMethod]
            public void HowTo_CheckSession_With_TennisApp() {
                var request = new Mock<HttpRequestBase>();
                request.Expect(r => r.HttpMethod).Returns("GET");     
    
                var httpContext = new Mock<HttpContextBase>();
                var session = new Mock<HttpSessionStateBase>();
    
                httpContext.Expect(c => c.Request).Returns(request.Object);
                httpContext.Expect(c => c.Session).Returns(session.Object);
    
                session.Expect(c => c.Add("test", "something here"));            
    
                var playerController = new NewPlayerSignupController();
                memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController);          
    
                session.VerifyAll(); // function is trying to add the desired item to the session in the constructor
                //TODO: Add Assertions   
            }
    

        5
  •  2
  •   Nick DeVore    16 年前

    Scott Hanselman有一篇关于如何 create a file upload quickapp与MVC合作,讨论吸烟问题,并特别指出“如何模仿不友好的事物。”

        6
  •  2
  •   Mathias Lykkegaard Lorenzen    12 年前

    我使用了以下解决方案-创建一个我的所有其他控制器都继承自的控制器。

    public class TestableController : Controller
    {
    
        public new HttpSessionStateBase Session
        {
            get
            {
                if (session == null)
                {
                    session = base.Session ?? new CustomSession();
                }
                return session;
            }
        }
        private HttpSessionStateBase session;
    
        public class CustomSession : HttpSessionStateBase
        {
    
            private readonly Dictionary<string, object> dictionary; 
    
            public CustomSession()
            {
                dictionary = new Dictionary<string, object>();
            }
    
            public override object this[string name]
            {
                get
                {
                    if (dictionary.ContainsKey(name))
                    {
                        return dictionary[name];
                    } else
                    {
                        return null;
                    }
                }
                set
                {
                    if (!dictionary.ContainsKey(name))
                    {
                        dictionary.Add(name, value);
                    }
                    else
                    {
                        dictionary[name] = value;
                    }
                }
            }
    
            //TODO: implement other methods here as needed to forefil the needs of the Session object. the above implementation was fine for my needs.
    
        }
    
    }
    

    然后按如下方式使用代码:

    public class MyController : TestableController { }
    
        7
  •  0
  •   Steve_0 Steve_0    15 年前