Click here to Skip to main content
15,867,141 members
Articles / DevOps / Unit Testing

Mocking Session State in an ASP.NET MVC4 Unit Test using Moq

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
11 Feb 2014CPOL 39.8K   7   3
Mocking Session State in an ASP.NET MVC4 Unit Test using Moq

I recently spent more time than I'd liked to figure out how to mock session state within an ASP.NET MVC test project. So here's the solution to that one, so hopefully you won't spend as much time as I did.

Important disclaimer: I was all over the dial to search for information, but most of what I dug up was related to ASP.NET MVC 3. This below solution works for me with ASP.NET MVC 4 and Moq as mocking framework.

Consider the following controller and single action-method.

C#
public class HomeController : Controller
{
public HomeController()
{
// default constructor, usually you'd inject some repository or what not here, 
// but for this example we'll keep it simple
}

public ViewResult TestMe()
{
System.Diagnostics.Debug.WriteLine(Session["selectedMonth"]);
System.Diagnostics.Debug.WriteLine(Session["selectedYear"]);
return View();
}
}

The action-method references the current httpcontext's Session collection. So if we instantiate a HomeController and try to obtain a ViewResult when calling the action-method, our unit test will fail with a NullReferenceException.

So, since the action-method wants to know about the Session collection, which resides in the HttpContext for the request to the method, we need to provide a HttpContext object. The below unit test code creates a mock HttpContext object, hooks it up to a mock Session object and passes it the instantiation of the controller - and the test will then pass, as now the action-method has a HttpContext to reach into and yank out the Session information.

C#
[TestMethod]
public void TestActionMethod()
{
// create the mock http context
var fakeHttpContext = new Mock();

// create a mock session object and hook it up to the mock http context
var sessionMock = new HttpSessionMock {{"selectedYear", 2013}, {"selectedMonth", 10}};
var mockSessionState = new Mock();
fakeHttpContext.Setup(ctx => ctx.Session).Returns(sessionMock);

// ... and here's how to attach a http context identity, just in case you'll come to need that, too
var fakeIdentity = new GenericIdentity("mno@ucsj.dk");
var principal = new GenericPrincipal(fakeIdentity, null);
fakeHttpContext.Setup(t => t.User).Returns(principal);

// we'll need to hook our http context up to a controller context mock - because 
// we can't provide our controller with the http context mock directly
var homeControllerMock = new Mock();
homeControllerMock.Setup(foo => foo.HttpContext).Returns(fakeHttpContext.Object);

// all set up, now we'll instantiate the controller and 
// pass our controller context object into its 'controllerContext' property
var target = new HomeController()
{
ControllerContext = homeControllerMock.Object
};

// ... and the below call to the action method won't throw a nullReferenceException, 
// because now it has a Session state to dig into
ViewResult result = target.TestMe();

// ... and so the test will pass
Assert.AreEqual(string.empty, result.ViewName);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Denmark Denmark
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionYour code didn't work for us, plz help for our situation Pin
Member 1130337915-Apr-16 2:04
Member 1130337915-Apr-16 2:04 
AnswerRe: Your code didn't work for us, plz help for our situation Pin
Member 1259416521-Sep-16 9:06
Member 1259416521-Sep-16 9:06 
QuestionCould you add sample code, please? Pin
Member 151403917-Feb-14 5:15
Member 151403917-Feb-14 5:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.