I currently use the following approach to create a strongly typed object representing session variables.
public abstract class SessionController : Controller { private const string SESSION_NAME = 'UserSession'; public SessionData SessionData { get { SessionData sessionData = (SessionData)Session[SESSION_NAME]; if (sessionData != null) { return sessionData; } else { sessionData = new SessionData(); Session[SESSION_NAME] = sessionData; return sessionData; } } set { Session[SESSION_NAME] = value; } } }
SessionData is a simple object like for example
[Serializable] public class SessionData { public String SessionId { get; set; } public Int64 UserId { get; set; } public String NameOfUser { get; set; } }
When creating a new Controller I derivate it from the SessionController so that I have strongley typed access to my SessionData. For example
public CityController : SessionController { [AcceptVerbs(HttpVerbs.Get)] public ActionResult Index() { ViewData.Model = _cityService.GetAll(SessionData.UserId); return View('Index'); } }
So, I am struggling at the moment to get this approached covered by a unittest. A shortened version of what I have tried is the following snippet
[SetUp] public void SetUp() { mocks = new MockRepository(); _cityService = MockRepository.GenerateStub<ICityService>(); _sesssionData = new SessionData { UserId = 1, SessionId = '1' }; // First Approach controller = new CityController(_cityService); controller.Expect(p => p.SessionData).Return(_sesssionData); // Second Approach cctx = MockRepository.GenerateStub<ControllerContext>(); cctx.Expect(p=>p.HttpContext.Session['UserSession'] as SessionData).Return(_sesssionData); controller.ControllerContext = cctx; }
Has anyone a tip on how to get this problem solved?
If you make your SessionData property virtual then your first approach could work:
IMO this approach is not very good because the SUT (Subject Under Test => in this case CityController) is being mocked with PartialMock.