Testing HttpHandlers
September 19, 2012 Leave a comment
For experienced web-developers this post will not bring any news but I hope beginners in Microsoft web technologies (like myself) will find it helpful.
Recently I started to work on a web project where I have to deal with custom HttpHandlers
. They implement the IHttpHandler
interface which looks like this:
public interface IHttpHandler { bool IsReusable { get; } void ProcessRequest(HttpContext context); }
The problem is the single parameter of the interface’s ProcessRequest
method. It’s really hard to work with HttpContext
in unit tests. Mocking request or response properties is almost impossible and feeding them the right data is also non-trivial.
Microsoft noticed that as well some time in the past and offered an abstract base class called HttpContextBase
which looks (almost) exactly like the original HttpContext
but lets you override each and any property or method to return your desired values. But although the name suggests otherwise HttpContext
does not derive from HttpContextBase
. So what’s the use of it anyway?!?
There is a third class called HttpContextWrapper
(derived from HttpContextBase
) which wraps an instance of the HttpContext
and serves as an adapter to the API provided by HttpContextBase
.
So now we have an adapter for the real thing we can implement a custom handler like this:
public class MyHttpHandler : IHttpHandler { void IHttpHandler.ProcessRequest(HttpContext context) { Guard.AssertNotNull(context, "context); HttpContextBase wrapper = new HttpContextWrapper(context); this.ProcessRequest(wrapper); } public void ProcessRequest(HttpContextBase context) { // ... do your magic here } }
We still can’t test the implementation of IHttpHandler.ProcessRequest
directly. But I’m positive that Microsoft invested some work into the HttpContextWrapper
so I think it’s safe to assume that it works as expected. And the three lines in that implementation are really trivial enough to exclude them from our test suite without bad conscience.
So what do we gain? Testing ProcessRequest(HttpContextBase)
is a piece of cake now that we can manipulate the data served by a mock implementation of HttpContextBase
. By that we can simulate input conditions that would be hard to fake using an instance of the real HttpContext
.
Btw.: There are abstractions for other concrete classes from System.Web
like HttpApplicationState
, HttpResponse
, HttpRequest
or HttpServerUtility
and many more.