Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing an HttpApplication

I have a class derived from HttpApplication that adds some extra features. I'm to the point where I need to unit test these features, which means I have to be able to create a new instance of the HttpApplication, fake a request, and retrieve the response object.

How exactly do I go about unit testing an HttpApplication object? I'm using Moq at the moment, but I have no idea how to set up the required mock object.

like image 980
David Brown Avatar asked Jul 25 '09 15:07

David Brown


People also ask

Is it possible to unit test Web API?

You can either create a unit test project when creating your application or add a unit test project to an existing application. This tutorial shows both methods for creating a unit test project. To follow this tutorial, you can use either approach.

What is meant by unit testing?

Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.

What are unit testing techniques?

Unit testing, a testing technique using which individual modules are tested to determine if there are any issues by the developer himself. It is concerned with functional correctness of the standalone modules. The main aim is to isolate each unit of the system to identify, analyze and fix the defects.


2 Answers

Unfortunately, this isn't particularly easy to do, as the HttpApplication doesn't lend itself to mocking very easily; there is no interface to mock against and most of the methods aren't marked as virtual.

I recently had a similar problem with HttpRequest and HttpWebResponse. In the end, the solution I went for was to create a straight "pass-through" wrapper for the methods I wanted to use:

public class HttpWebRequestWrapper : IHttpWebRequestWrapper
    {
        private HttpWebRequest httpWebRequest;

        public HttpWebRequestWrapper(Uri url)
        {
            this.httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        }

        public Stream GetRequestStream()
        {
            return this.httpWebRequest.GetRequestStream();
        }

        public IHttpWebResponseWrapper GetResponse()
        {
            return new HttpWebResponseWrapper(this.httpWebRequest.GetResponse());
        }

        public Int64 ContentLength
        {
            get { return this.httpWebRequest.ContentLength; }
            set { this.httpWebRequest.ContentLength = value; }
        }

        public string Method 
        {
            get { return this.httpWebRequest.Method; }
            set { this.httpWebRequest.Method = value; }
        }

        public string ContentType
        {
            get { return this.httpWebRequest.ContentType; }
            set { this.httpWebRequest.ContentType = value; }
        }
}

etc, etc

This let me mock against my own wrapper interface. Not necessarily the most elegant thing in the world, but a very useful way of mocking out some of the less "mockable" parts of the framework.

Before you rush off and do this though, it is worth reviewing what you've got and seeing if there is a better approach to your tests that would avoid you having to wrap classes.

In the case of HttpWebRequest, HttpApplication et al, there often isn't IMHO.

In order to set this wrapper in mock (using my HttpWebRequest example above) you then do stuff like this with Moq:

var mockWebRequest = new Mock<IHttpWebRequestWrapper>();
mockWebRequest.SetupSet<string>(c => c.Method = "POST").Verifiable();
mockWebRequest.SetupSet<string>(c => c.ContentType = "application/x-www-form-urlencoded").Verifiable();
mockWebRequest.SetupSet<int>(c => c.ContentLength = 0).Verifiable();
like image 140
Rob Levine Avatar answered Oct 19 '22 20:10

Rob Levine


IMHO adding a functionality by extending HttpApplication is not the best thing to do. It is so difficult to mock the HttpContext because of the private/internal/sealed classes that even if you succeed your unit tests will be so cluttered with mocking code that you will no longer be able to understand what you are actually testing.

Could you give more details on what functionality you are adding? Maybe there's a better way of adding this functionality to your application.

like image 2
Darin Dimitrov Avatar answered Oct 19 '22 22:10

Darin Dimitrov