Reputation: 207
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
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