Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking sealed classes without public constructors?

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?

like image 698
Peter Smith Avatar asked Feb 06 '12 04:02

Peter Smith


People also ask

Can sealed class be mocked?

Even the sealed class has only an internal constructor, you can still create a mock, call its members and verify the results.

Can sealed class have constructor?

Sealed class rules Sealed classes are abstract and can have abstract members. Sealed classes cannot be instantiated directly. Sealed classes cannot have public constructors (The constructors are private by default).

Can we instantiate sealed class?

A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.

Can we override sealed class in C#?

You can't inherit from a sealed class, so no inheritance, no override. The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event. When applied to a class, the sealed modifier prevents other classes from inheriting from it.


3 Answers

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.

like image 190
Mark W Avatar answered Oct 19 '22 10:10

Mark W


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.

like image 26
jhsowter Avatar answered Oct 19 '22 09:10

jhsowter


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.

like image 27
Scott Lerch Avatar answered Oct 19 '22 08:10

Scott Lerch