单元测试无法识别会话

时间:2016-10-31 00:28:13

标签: c# asp.net asp.net-mvc unit-testing session

我一直致力于ASP.NET MVC项目Visual Studio 2012 Ultimate with Entity Framework。我必须在我的解决方案中包含一个单元测试项目。我的问题在于测试方法(称为Index())无法识别会话 在控制器的Index()动作中。我的单元测试方法是:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using ELSORegistry;
using ELSORegistry.DataAccess;
using ELSORegistry.Controllers;



namespace ELSORegistryUnitTests
{
    [TestClass]
    public class FirstControllerTest
    {
        [TestMethod]
        public void Index()
        {
            //Arange
            HomeController controller = new HomeController();

            //Act
            Guid? myGuid = new Guid("941b1615-f21b-4e2c-8fa8-0ed0d3f2de53");
            ViewResult result = controller.Index(myGuid) as ViewResult;

            //Assert
            Assert.IsNotNull(result);
        }
    }
}

Home Controller中的我的Index()动作是:

using System;
using System.Diagnostics.Contracts;
using System.Web.Mvc;
using ELSORegistry.DataAccess;
using ELSORegistry.Models;
using Kendo.Mvc.UI;
using WebGrease.Css.Extensions;
using ELSORegistry.Extensions;



using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Linq;
using Kendo.Mvc.Extensions;
using System.Diagnostics;
using ELSORegistry.Helpers;
using Newtonsoft.Json;


namespace ELSORegistry.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        [Authorize(Roles = "ECLS Center Data Manager, ECLS Center Administrator,ECLS Center Data Viewer, ECLS Center Data Entry")]
        //[RequireHttps]  // Enable for production
        public ActionResult Index(Guid? CenterId)
        {
            //----------------------------------------
            // Remove references to previous patients
            //----------------------------------------    
            Session.Remove("Patient");
            Session.Remove("PatientSummary");
            Session.Remove("Run");
            Session.Remove("RunDetail");
            Session.Remove("Addendum");

            // if user have this session then he will get edit forms. // Yes if Add new
            Session.Remove("AddNewMode");
            Session.Remove("AddNewRunId");
            Center center;
            if (CenterId == null)
            {
                center = Session["Center"] as Center;
                Contract.Assert(center != null);
            }
            else
            { // set center by selected centerId from dropdownlist
                center = new Repository().GetCenter(new Guid(CenterId.ToString()));
                Session["Center"] = center;
                center = Session["Center"] as Center;
                Contract.Assert(center != null);
            }


            ViewBag.RunCounts = Session["RunCounts"];
            ViewBag.ChartSummaries = Session["ChartSummaries"];



            return View(new QuickAdd());

        }

如何从单元测试方法中允许会话?提前感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

手动创建模拟会话或使用模拟框架模拟会话,该会话将成为http上下文的一部分。基本上,这种安排是复制框架在运行时会做的事情。

[TestMethod]
public void Index() {
    //Arange
    Guid? myGuid = new Guid("941b1615-f21b-4e2c-8fa8-0ed0d3f2de53");
    var center = new Center();
    var session = Mock.Of<HttpSessionStateBase>();
    session["Center"] = center;
    var mockSession = Mock.Get(session);
    mockSession.Setup(m => m["Center"]).Returns(center);

    var httpcontext = Mock.Of<HttpContextBase>();
    var httpcontextSetup = Mock.Get(httpcontext);
    httpcontextSetup.Setup(m => m.Session).Returns(session);

    var mockRepository = new Mock<IRepository>();
    mockRepository.Setup(m => m.GetCenter(myGuid.Value)).Returns(center);

    HomeController controller = new HomeController(mockRepository.Object);
    controller.ControllerContext = new ControllerContext {
        HttpContext = httpcontext,
        Controller = controller
    };

    //Act
    ViewResult result = controller.Index(myGuid) as ViewResult;

    //Assert
    Assert.IsNotNull(result);
}

上面的示例使用Moq来模拟依赖项。控制器也经过重构,通过抽象存储库来提高测试能力。

public interface IRepository {
    Center GetCenter(Guid guid);
}

public class Repository : IRepository {
    //...other code removed for brevity
}

[Authorize]
public class HomeController : Controller {
    private IRepository repository;

    public HomeController(IRepository repository) {
        this.repository = repository;
    }

    [Authorize(Roles = "ECLS Center Data Manager, ECLS Center Administrator,ECLS Center Data Viewer, ECLS Center Data Entry")]
    //[RequireHttps]  // Enable for production
    public ActionResult Index(Guid? CenterId) {
        //----------------------------------------
        // Remove references to previous patients
        //----------------------------------------    
        Session.Remove("Patient");
        Session.Remove("PatientSummary");
        Session.Remove("Run");
        Session.Remove("RunDetail");
        Session.Remove("Addendum");

        // if user have this session then he will get edit forms. // Yes if Add new
        Session.Remove("AddNewMode");
        Session.Remove("AddNewRunId");
        Center center;
        if (CenterId.GetValueOrDefault() == Guid.Empty) {
            center = Session["Center"] as Center;
            Contract.Assert(center != null);
        } else { // set center by selected centerId from dropdownlist
            center = repository.GetCenter(CenterId.Value);
            Session["Center"] = center;
            center = Session["Center"] as Center;
            Contract.Assert(center != null);
        }

        ViewBag.RunCounts = Session["RunCounts"];
        ViewBag.ChartSummaries = Session["ChartSummaries"];

        return View(new QuickAdd());
    }
}