【问题标题】:Unit testing sessions is still returning null after Mocking模拟后单元测试会话仍然返回 null
【发布时间】:2016-05-25 07:14:59
【问题描述】:

我正在尝试编写一个单元测试来测试我使用会话的控制器。我理解 httpcontext 仅由来自浏览器的请求生成的概念,并且由于调用控制器操作表单单元测试,当前上下文将为空。

我尝试根据本文的第一部分http://www.dontpaniclabs.com/blog/post/2011/03/22/testing-session-in-mvc-in-four-lines-of-code/ 解决此问题,但它仍然不适合我。请参阅下面的代码。

    [TestFixtureSetUp]
    public void Configure_AutoMapper()
    {
        _product = new ProductViewModel()
        {
            Id = Guid.NewGuid(),
            Category = Guid.Parse("72E42A11-DFA4-4AB9-A735-5CD5C18396D4"),
            Brand = Guid.Parse("96E68B67-60FB-4531-898E-815433B44D89"),
            Description = "From test",
            CostPrice = Parse("17.00"),
            SalePrice = Parse("25.00"),
            Quantity = 7,
            BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415")
        };

        var context = new Mock<ControllerContext>();
        var session = new Mock<HttpSessionStateBase>();
        context.Setup(m => m.HttpContext.Session).Returns(session.Object);
        _productsController = new ProductsController {ControllerContext = context.Object};

        var userSessionInfo = new UserSessionViewModel()
        {
            FirstName = "Junior",
            LastName = "Labolz",
            BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415")
        };

        SessionHelper.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo);
    }


    [Test]
    public void Display_Products_List_On_View_Products_Button_Click()
    {
        //Set Up

        //Act
        var viewResult = (ViewResult)_productsController.Index();

        //Assert
        Assert.That(string.Empty, Is.EqualTo(viewResult.ViewName));
    }


    public static void AddUserDetailsToSession(string sessionName, UserSessionViewModel userSessionDetails)
    {
        HttpContext.Current.Session.Add(sessionName, userSessionDetails);
    }

**根据 Richard 的回答,我将其更改为 **

        var context = new Mock<ControllerContext>();
        var session = new Mock<HttpSessionStateBase>();
        context.Setup(m => m.HttpContext.Session).Returns(session.Object);
        var userSessionInfo = new UserSessionViewModel()
        {
            FirstName = "Junior",
            LastName = "Labolz",
            BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415")
        };
        context.Object.HttpContext.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo);

        _productsController = new ProductsController {ControllerContext = context.Object};

产品控制器构造函数

    public ProductsController()
    {
        _productService = new ProductServiceClient();
        _userSessionViewModel = (UserSessionViewModel)SessionHelper.GetSessionDetail(SessionHelper.UserDetails);
    }

获取会话方法

    public static object GetSessionDetail(string sessionName)
    {
        return HttpContext.Current.Session[sessionName];
    }

【问题讨论】:

    标签: asp.net-mvc unit-testing session mocking httpcontext


    【解决方案1】:

    我可以看到您的代码包含一个直接引用 HttpContext.Current 的静态函数。如果要进行单元测试,则不能这样做,而必须使用注入的 HttpContextBase 实例。

    在您的单元测试中,这些实例将成为您的模拟上下文。在生产环境中,您可以将容器设置为在请求 HttpContextBase 时注入 HttpContext.Current。

    我会将您的静态方法重写为扩展方法:

    public static void AddUserDetailsToSession(this HttpContextBase context, 
        string sessionName, UserSessionViewModel userSessionDetails)
    {
        context.Session.Add(sessionName, userSessionDetails);
    }
    

    然后从您的测试中调用它:

    context.Object.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo);
    

    【讨论】:

    • 我仍然收到空引用异常,可能是因为我还试图在我的 productController 构造函数中读取会话?
    • 我已经更新了我的代码,请找我。我将其更改为使用扩展方法,我的更新中有一个标题“基于理查德的回答”。我还向您展示了我的产品控制器中的内容
    • 您不能在任何地方使用 HttpContext.Current - 您可以从 ControllerContext 获取 HttpContext。无论如何,您都不应该从控制器构造函数访问 Session,因为在调用它时您没有上下文。
    • 注意!谢谢,在我的控制器中,我现在使用 var userSessionViewModel = (UserSessionViewModel)this.ControllerContext.HttpContext.Session[SessionHelper.UserDetails];但这将 userSessionViewModel 设置为 null,但我认为我已经将控制器上下文会话设置为测试中的值,为什么在我尝试从控制器中的控制器上下文获取会话后它仍然返回 null
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2020-12-16
    相关资源
    最近更新 更多