Mocking HttpContext – Adding Sessions

Summary

In one of my previous posts (See: Mocking HttpContext), I created a HttpContext factory and a mocked HttpContext object that can be used to simulate the HttpContext.Current object used by methods under a unit test.  In this post, I’m going to add the Session capabilities to this object so you can unit test your methods and fake or mock your session variables.

The Mock Indexer

The session indexer can be overridden by creating a class based on the HttpSessionStateBase class.  Once this is done, then it can be used the Session object of the HttpContext.  Here’s the class to override the indexer:

public class MockHttpSession : HttpSessionStateBase
{
    public SessionStateItemCollection SessionVariables = new SessionStateItemCollection();
    public override object this[string name]
    {
        get
        {
            return SessionVariables[name];
        }
        set
        {
            SessionVariables[name] = value;
        }
    }
}

You’ll have to add a “using using System.Web.SessionState;” at the top for HttpSessionStateBase to be available.

Adding to the MockHttpContext

Next, you’ll need to add another public variable to the top of the existing MockHttpContext object and then add a Setup() method to replace the Session object.  Your MockHttpContext object will look like this:

public class MockHttpContext
{
    public NameValueCollection ServerVariables = new NameValueCollection();
    public HttpCookieCollection Cookies = new HttpCookieCollection();
    public NameValueCollection HeaderVariables = new NameValueCollection();
    public MockHttpSession SessionVars = new MockHttpSession();
    public HttpContextBase Context
    {
        get
        {
            var httpRequest = new Moq.Mock<HttpRequestBase>();
            httpRequest.Setup(x => x.ServerVariables.Get(It.IsAny<string>()))
                .Returns<string>(x =>
                {
                    return ServerVariables[x];
                });
            httpRequest.SetupGet(x => x.Cookies).Returns(Cookies);
            httpRequest.Setup(x => x.Headers.Get(It.IsAny<string>()))
                .Returns<string>(x =>
                    {
                        return HeaderVariables[x];
                    }
                );
            var httpContext = (new Moq.Mock<HttpContextBase>());
            httpContext.Setup(x => x.Request).Returns(httpRequest.Object);
            httpContext.Setup(ctx => ctx.Session).Returns(SessionVars);
            return httpContext.Object;
        }
    }
}

You’ll need to include Moq (use NuGet to find and install), and you’ll need to include the following using statements:

using System.Collections.Specialized;
using System.Web;
using System.Web.SessionState;
using Moq;

The Unit Test

The new unit test would look roughly like this:

[TestMethod]
public void httpcontext_session()
{
    var tempContext = new MockHttpContext();
    HttpContextFactory.SetCurrentContext(tempContext.Context);
    HttpContextFactory.Current.Session["testid"] = "test data";
    //TODO: call http method under test
    Assert.AreEqual("test data", HttpContextFactory.Current.Session["testid"]);
}

This unit test uses the same HttpContextFactory as shown in my previous blog post.  The entire working code can be found on my GitHub account.

Where to Get the Code

As usual, you can go to my GitHub account and download the entire project by clicking here.

Leave a Reply