2
votes

I have recently Implemented a unit of work pattern, and as an environment we are using more unit testing. Currently the implementation writes into a session helper that writes to session. How do I unit test these aspects in regard to the session? Should I make a repository pattern? (repository interface with concrete session implementation and concrete mock implementation) How is this normally done?

I know there is probably more than one way of approaching this, but I am just looking for some advice.

2

2 Answers

8
votes

There are basically two ways of doing this.

Assuming you are using .NET 3.5 or up. Change your implementation to take the HttpSessionStateBase object as a constructor parameter, you can then mock this implementation - there's a few tutorials online on how to do this. You can then use an IoC container to wire this up at app start or do something like (poor man's dependency injection):

public class MyObjectThatUsesSession
{
    HttpSessionStateBase _session;

    public MyObjectThatUsesSession(HttpSessionStateBase sesssion)
    {
         _session = session ?? new HttpSessionStateWrapper(HttpContext.Current.Session);
    }

    public MyObjectThatUsesSession() : this(null)
    {}
}

Alternatively, and probably a bit better and more flexible design would be to create a test seam by wrapping your interaction with session in another object. You could then change this to a database, cookie or cache based implementation later. Something like:

public class MyObjectThatUsesSession
{
    IStateStorage _storage;

    public MyObjectThatUsesSession(IStateStorage storage)
    {
         _storage= storage ?? new SessionStorage();
    }

    public MyObjectThatUsesSession() : this(null)
    {}

    public void DoSomethingWithSession()
    {
        var something = _storage.Get("MySessionKey");
        Console.WriteLine("Got " + something);
    }
}

public interface IStateStorage
{
    string Get(string key);
    void Set(string key, string data);
}

public class SessionStorage : IStateStorage
{
    //TODO: refactor to inject HttpSessionStateBase rather than using HttpContext.

    public string Get(string key)
    {
       return HttpContext.Current.Session[key];
    }

    public string Set(string key, string data)
    {
       HttpContext.Current.Session[key] = data;
    }
}

You can then use Moq to create a mock IStateStorage implementation for your tests or create a simple dictionary based implementation.

Hope that helps.

0
votes

Somewhat vague question, but I still try to get you some ideas. Probably, you'll be able to clarify your question a bit.

You can substitute your session helper with mock, spy or fake object. So after finishing unit of work you can verify that all necessary data reached session helper. In my opinion fake object is preferable, but I do not know enough details about your case. How to deliver this fake to session depends on your design. Session helper can be passed into unit of work during its construction, for instance. Or you can use repository as you've written, but then you must inject repository into unit of work and probably create additional fake repository to return fake session helpers. Other solutions also exist.

Note that details of interaction between session helper and session itself also should be separately unit tested. But if your session helper is a very simple object then you can test that data correctly reach session. Thus, your session helper will be tested indirectly and you'll need not bother with creating separate test.