views:

805

answers:

1

I am trying to test a 'plugin' for an ASPNET HttpApplication that is loaded on Application_Start. The code is something like this:

    private HttpApplication application;

    public void Application_Start(object sender, EventArgs e)
    {
        this.application = sender as HttpApplication;

        StartReportService();
    }

    private void StartReportService()
    {

        HandledReports = new SortedList<string, string>();
        HandledReports.Add("myindex","myvalue");

    }

    public System.Collections.Generic.SortedList<String, String> HandledReports
    {
        get 
        {
            application.Application.Lock();
            var handledReports = (SortedList<String, String>)application.Application["handledReports"];
            application.Application.UnLock();
            return handledReports;
        }
        set 
        { 
            application.Application.Lock();
            application.Application["handledReports"] = value; 
            application.Application.UnLock();
        }
    }

The problem is that I cannot find a good way to test the HttpApplicationState mainly because the HttpApplication.Application property is not overridable and there does not seem to be a HttpApplicationBase class in the System.Web.Abstractions that would allow this.

I have tried variations of the following, always running into a road block each time.

[TestMethod()]
public void StartReportService_ApplicationStateShouldContainMyIndex()
{
    //No HttpApplicationBase in System.Web.Abstractions, must use Real Object
    var application = new Mock<HttpApplication>();

    //Real object does not have a property of type HttpApplicationStateBase so must use real one?
    //var applicationStateBase = new Mock<HttpApplicationStateBase>();

    //real one not creable so HACK get private constructor
    var ctor = typeof(HttpApplicationState).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { }, new ParameterModifier[] { });
    var applicationState = (HttpApplicationState)ctor.Invoke(new Object[] { });

    //fails here, HttpApplication.Application not overridable
    application.SetupProperty(x => x.Application, applicationState);


    var plugin = HttpApplicationPlugin.HttpApplicationPluginInstance;
    plugin.Application_Start(application.Object,null);

    ...evaluate result...
}

Could anyone shed some light on some good approaches for me? This is the first test of more that will rely on being able to have a functioning HttpApplicationState mocked.

TIA Simon

+1  A: 

Well with some careful thought and a bit of reflection :) , I came up with this solution to my own problem to get me going:

     [TestMethod()]
     public void StartReportService_ApplicationStateShouldContainMyIndex()
     {
        HttpApplicationPlugin plugin=null;
        HttpApplication app = null;
        HttpApplicationState applicationState = null;
        String tempDir = "";
        try
        {
            #region "Create HttpApplication and ApplicationState"

            //No HttpApplicationBase in System.Web.Abstractions, must use Real Object
            app = new HttpApplication();

            //real one not creatable so HACK get private constructor
            var ctor = typeof(HttpApplicationState).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { }, new ParameterModifier[] { });
            applicationState = (HttpApplicationState)ctor.Invoke(new Object[] { });

            //HACK in the state prop for testing
            var stateProp = typeof(HttpApplication).GetField("_state", BindingFlags.Instance | BindingFlags.NonPublic);
            stateProp.SetValue(app, applicationState);

            #endregion


           plugin = HttpApplicationPlugin.HttpApplicationPluginInstance;
           plugin.Application_Start(application.Object,null);

...evaluate result...

Essentially you can use reflection to give you an HttpApplication Object with a HttpApplicationState object that will suffice for testing code blocks that rely on this.

Simon Francesco