alenan2013
alenan2013

Reputation: 207

Unit test can't recognize sessions

I have been working on ASP.NET MVC project Visual Studio 2012 Ultimate with Entity Framework. I have to include a Unit Test project into my solution. My problem is in that the test method (called Index()) can't recognize the sessions in the Index() action of the controller. My Unit test method is:

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);
        }
    }
}

My Index() action in the Home Controller is:

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());

        }

How can I allow Sessions from my Unit test method? Thank you in advance for any help.

Upvotes: 1

Views: 1983

Answers (1)

Nkosi
Nkosi

Reputation: 246998

Either create a mock session manually or use a mocking framework to mock the session which would be part of a http context. Basically the arrangement is replicating what the framework would do when running.

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

The above example uses Moq to mock dependencies. The controller was also refactored to allow for better test-ability by abstracting the repository.

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());
    }
}

Upvotes: 3

Related Questions