British Inside

An Englishman living in small town America

James Shaw

News

  • Copyright James Shaw 2004-2007

    Creative Commons License

    View James Shaw's profile on LinkedIn

HttpServerUtility.HtmlEncode and unit testing

In Http objects and Unit testing I introduced you to my Context class that replaces the HttpContext classes such as Request, Response, Session, etc..allowing me to unit test my class libraries without fear.

During some real-world testing on my staging server yesterday I got tripped up by two bugs not trapped by the unit testing. Of course the first thing is to write some unit tests that show up the bug - that way if they ever show up again I have a chance of the unit tests telling me early.

And there's the problem - way down deep in the class I needed to test there's a call to HttpContext.Current.Server.HtmlEncode().

Interesting because I thought I had replaced all HttpContext.Current with Context calls? So I did the replacement and found that it threw a NotImplemented exception:

/// <summary> /// console-safe version of HttpContext.Current.Server /// </summary> public static HttpServerUtility Server { get { if (HttpContext.Current != null) return HttpContext.Current.Server; throw new NotImplementedException(); } }

Ah, yes. I remember. In most cases (like with HttpResponse) I can simply instantiate a class and return that instance when unit testing. It's not populated perfectly of course without a real context but I've found it works well enough.

The problem with HttpServerUtility is that there is no public constructor. You can go through all these hoops to try and instantiate one..

System.IO.TextWriter output = new System.IO.StringWriter(); HttpWorkerRequest wr =
new SimpleWorkerRequest("page", "", output); HttpContext context = new HttpContext(wr); return new HttpServerUtility(context);

..and end up just staring at..

System.Web.HttpServerUtility.HttpServerUtility(System.Web.HttpContext)' is inaccessible due to its protection level

HttpServerUtility constructors are internal to System.Web. In other words, "You lose, sucker".

So let's fire up Reflector and scour System.Web for any way to instantiate HttpServerUtility. I quickly find that HttpApplication has a Server property and that it returns the HttpContext.Server if HttpContext is not null, otherwise it returns a new instance:

public HttpServerUtility Server { get { if (this._context != null) { return this._context.Server; } return new HttpServerUtility(this); } }

Perfect! So all I have to do is rewrite my HttpServer wrapper like this..

/// <summary> /// console-safe version of HttpContext.Current.Server /// </summary> public static HttpServerUtility Server { get { if (HttpContext.Current != null) return HttpContext.Current.Server; if (_app == null) _app = new HttpApplication(); return _app.Server; } }

..and write a quick unit test to check that it works..

[Test] public void TestServer() { Assert.IsNotNull(Context.Server); Assert.AreEqual("&lt;", Context.Server.HtmlEncode("<")); }

..and now I can write unit tests for even more of my code that uses HtmlEncode().

Posted: Saturday, August 20, 2005 10:11 AM by James

Comments

Michael Freidgeim said:

Your link "Http objects and Unit testing" is not working(refers to localhost)
# April 13, 2007 12:38 AM

James said:

Thanks Michael!

# April 13, 2007 6:07 AM
New Comments to this post are disabled