6

The particular class I'm testing depends upon the HttpSessionState object.

The HttpSessionState class has no public constructors. The class under test is only using this object as a NameValue store. The class is used in an ASMX web service to return information for a particular method.

I'm thinking about creating a facade around the HttpSessionState class where I can provide a Dictionary <string, string> instead of the Session object in testing.

Is this a good idea or standard practice?

Peter Smith
  • 849
  • 2
  • 11
  • 28

3 Answers3

8

Yep, as the old saying goes, there's nothing that can't be solved by adding another layer of abstraction. I usually just hide the type behind an interface where the interface's methods are the only ones needed to perform the actions I want on that type.

Just mock the interface that hides HttpSessionState, and do Asserts on the uses of the interface, in Rhino Mocks it's just AssertWasCalled(d => ....) etc.

Mark W
  • 3,879
  • 2
  • 37
  • 53
  • 3
    "there's nothing that can't be solved by adding another layer of abstraction" - except "to much layers of abstractions" =) – Restuta Feb 06 '12 at 04:17
  • I believe the original was, "there's nothing that another level of indirection can't solve." At some point though you won't be able to test a level, such as what you're hiding httpsessionstate in. Not familiar with it but guessing you can't really unit test it, but you can test the SUT if it's using a type like this to do "something". – Mark W Feb 06 '12 at 04:21
  • I don't care about original, it's just true =) – Restuta Feb 06 '12 at 09:24
2

You can create a sub-class of the HttpSessionStateBase class. This answer shows how to implement this for Moq, but you can still use the MockHttpSession class with your Rhino Mocks (I assume. I haven't used Rhino Mocks).

public class MockHttpSession : HttpSessionStateBase
{
    Dictionary<string, object> sessionStorage = new Dictionary<string, object>();

    public override object this[string name]
    {
        get { return sessionStorage[name]; }
        set { sessionStorage[name] = value; }
    }
}

A fairly extensive discussion about how to mock .NET classes can be found at Scott Hanselman's blog here.

Community
  • 1
  • 1
jhsowter
  • 619
  • 3
  • 8
2

You can mock any type even sealed ones using Microsoft's Moles Isolation framework for .NET. Takes a little work to setup but might be better than adding another layer of abstraction. Mocking HttpContext and HttpSessionState using moles is discussed here. There is another similar discussion here.

Community
  • 1
  • 1
Scott Lerch
  • 2,620
  • 1
  • 23
  • 34
  • 2
    I am not sure that to get another one project dependency, read as "brand new isolation framework" is simplier solution (read as better) that one tiny abstraction. – Restuta Feb 06 '12 at 09:26
  • @Restuta, yeah, you're probably right, but it's an option and answers at least the title of the question "Mocking sealed classes" – Scott Lerch Feb 06 '12 at 17:09