当前位置:  开发笔记 > 后端 > 正文

ASP/NET MVC:测试控制器是否有会话?惩戒?

如何解决《ASP/NETMVC:测试控制器是否有会话?惩戒?》经验,为你挑选了4个好方法。

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



1> David P..:

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

ASP.NET MVC技巧#12 - 伪造控制器上下文

[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"]);
}


我不得不挖掘这个网址,所以这里是:http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context.aspx
它可能并不明显,但FakeControllerContext是一个自定义类.你可以在这里看到它的来源:http://stephenwalther.com/Downloads/Tips/Tip12/Tip12.zip

2> chadmyers..:

ASP.NET MVC框架不是非常模拟友好的(或者更确切地说,需要太多的设置才能正确地进行模拟,并且在测试时会导致太多摩擦,恕我直言),因为它使用了抽象基类而不是接口.我们很幸运为每个请求和基于会话的存储编写抽象.我们保持这些抽象非常轻,然后我们的控制器依赖于每个请求或每个会话存储的抽象.

例如,这是我们如何管理表单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> Dane O'Conno..:

使用MVC RC 1,ControllerContext包装HttpContext并将其作为属性公开.这使得模拟更容易.要使用Moq模拟会话变量,请执行以下操作:

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

有关详细信息,请参阅Scott Gu的帖子.



4> Korbin..:

我觉得嘲笑相当容易.下面是使用moq模拟httpContextbase(包含请求,会话和响应对象)的示例.

[TestMethod]
        public void HowTo_CheckSession_With_TennisApp() {
            var request = new Mock();
            request.Expect(r => r.HttpMethod).Returns("GET");     

            var httpContext = new Mock();
            var session = new Mock();

            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   
        }

希望有所帮助.


哇,这只是模拟一个方法的很多工作:)这显然是"太多的设置"气味,它是使用抽象基类而不是接口作为依赖关系的结果.
推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有