Opening up Monorail’s SmartDispatchController for easy unit testing

Monorail’s SmartDispatchController is fantastic.  One small hurdle is testability right out of the box.  For instance, if I have a controller action:

public void Foo()
{
    Session["somekey"] = new object();
}
 
If I want to unit test this action, I need to get at the Session IDictionary.  It’s protected, so I can’t get at it in a unit test to ensure the object was added to session.
 
Here is a quick way around this problem:
 
Make your own controller base class that derives from SmartDispatchController.  Then add the following method to the base class:
 
 
public new virtual IDictionary Session
{
    get { return base.Session; }
}

Now, for testing you can get at the Session property, but at runtime, there is no change.

2 comments

  1. Hi Jeffrey,

    Welcome to the party. You should check out Castle.MonoRail.TestSupport.BaseControllerTests or our approach we wrote before it existed:

    http://blog.eleutian.com/PermaLink,guid,e9abf4e0-10f6-4c28-8494-b79ebb0d5ffa.aspx
    http://blog.eleutian.com/2007/03/28/EleutianControllerTests20.aspx

    Session is part of the response. The real problem is not being able to mock the response or the request, and both of these approaches solve it in a non-invasive way.

  2. @Jeffrey:
    For this exact scenario we have the BaseControllerTest as Aaron pointed out.

    In general, I would have also considered a slightly different approach, using an explicit interface:
    IDictionary IControllerWithTestAccess.Session
    {
    get { return this.Session; }
    }

    so you’d only be able to access it if you explicitly cast to “WithTestAccess”;

    warning – notepad code. Not sure you can use the same prop name for explicit interface.

Comments are closed.