views:

204

answers:

2

I've seen how to Fake the SessionState object in MVC using Scott Hanselmans MvcMockHelpers, but I'm dealing with a separate problem.

What I like to do is create a wrapper around the Session object to make objects a little more accessible and strongly typed rather than using keys all over. Here is basically what it does:

public class SessionVars
{ 
    public SessionVars()
    {}

    public string CheckoutEmail
    {
        get { return Session[checkoutEmailKey] as string; }
        set { Session[checkoutEmailKey] = value; }
    }
}

So that I can just do this in my controllers and views:

SessionVars s = new SessionVars();
s.CheckoutEmail = "[email protected]";

Now the problem comes in when I want to write unit tests, this class is tightly coupled with the HttpSessionState. What I can't figure out is what is the right class to accept/pass so that I can pass in a FakeHttpSession into the SessionVars class. I've tried so many things with this, and this (below) will compile, but it can't cast the HttpSessionState into the IDictionary. I've tried ICollection, HttpSessionStateBase.

public class SessionVars
{
    public SessionVars() : this(HttpContext.Current.Session) { }
    public SessionVars(ICollection session)
    {
        Session = (IDictionary<string, object>)session;
    }

    public IDictionary<string, object> Session
    {
        get;
        private set;
    }

    public string CheckoutEmail
    {
        get { return Session[checkoutEmailKey] as string; }
        set { Session[checkoutEmailKey] = value; }
    }

    public Order Order
    {
        get { return Session[orderKey] as Order; }
        set { Session[orderKey] = value; }
    }
}

I'm missing something big here. I feel like this is possible and that I should even be that far off.

+1  A: 

My implementation of session helper (for inspiration):

http://github.com/Necroskillz/NecroNetToolkit/blob/master/Source/NecroNet.Toolkit/SessionData.cs

http://github.com/Necroskillz/NecroNetToolkit/blob/master/Source/NecroNet.Toolkit/ILocalDataProvider.cs

Also, you could either use concrete HttpSessionState in unit tests (here's how to create it: http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx), or you could use HttpSessionStateBase, but then you'd have to initialize your helper with appropriate object provided by MVC (something like ControllerContext.HttpContext.Session).

Necros
A: 

Have you tried to use the HttpSessionStateWrapper from System.Web.Abstractions?

it can be as easy as:

new HttpSessionStateWrapper(Session)

You can mock HttpSessionStateWrapper.

graffic
Can you provide an example? I can mock the session in a test, I understand that. What I don't get is how to setup my SessionVars class so that I can inject a mocked version. I didn't know this class existed, so now I'm even further confused about whether to use the HttpSessionStateBase, IHttpSessionState or HttpSessionStateWrapper. What is the type of the abstracted version of the Session object in my SessionVars class?
MaseBase
Actually, I think I get what you mean. This is what I was missing, the fact that I can't go from HttpSessionState to HttpSessionStateBase without using the HttpSessionStateWrapper class you've mentioned here.
MaseBase