I was recently looking for a way to unit test a piece of security code that would retrieve the User principal from the current HttpContext in an ASP.NET scenario. Now it was just a plain unit test, not a web test, so I didn't actually have an HttpContext. But how hard could it be to cook one up, right?
So I first tried to set the HttpContext.Current property, but IntelliSense popped up to say: "Gets the HttpContext object for the current HTTP request". So I figure it's a read-only property (because the phrase starts with "Gets...", where read-write properties typically start with "Gets or sets...") and I can't do it directly.
Then I found a post by Steve Maine that seemed to allow setting the current HttpContext by injecting it into the messaging CallContext of .NET Remoting. While that looks like a bit of black magic, I'm never too shy to throw in some snake blood and salamander eyes if it makes my code compile so I tried that, but it didn't seem to work right away. It did, however, provide me with a good way of creating a dummy HttpContext in the first place, which I also needed to do:
SimpleWorkerRequest request = new SimpleWorkerRequest("/dummy", @"c:\inetpub\wwwroot\dummy", "dummy.html", null, new StringWriter());
HttpContext context = new HttpContext(request);
So we just create a dummy worker request that the HttpContext requires and we pass it into the constructor.
Because the black magic wasn't working for me, I looked at the HttpContext class in my favorite .NET tool of all time, and quickly realized that the property was settable anyway [1]. So I guess that salamander had a lucky day:
HttpContext.Current = context;
And we're done. A valid current HttpContext for use in unit tests.
[1] Side comment: property documentation that doesn't follow the "Gets..." versus "Gets or sets..." pattern is pretty frustrating. It could have saved me quite some time if the documentation would just say "Gets or sets the HttpContext object for the current HTTP request"...