Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is HttpContextWrapper all that....useful?

I've been going through the process of cleaning up our controller code to make each action as testable. Generally speaking, this hasn't been too difficult--where we have opportunity to use a fixed object, like say FormsAuthentication, we generally introduce some form of wrapper as appropriate and be on our merry way.

For reasons not particularly germaine to this conversation, when it came to dealing with usage of HttpContext, we decided to use the newly created HttpContextWrapper class rather than inventing something homegrown. One thing we did introduce was the ability to swap in a HttpContextWrapper (like say, for unit testing). This was wholly inspired by the way Oren Eini handles unit testing with DateTimes (see article, a pattern we also use)

public static class FooHttpContext {     public static Func<HttpContextWrapper> Current = ()           => new HttpContextWrapper(HttpContext.Current);      public static void Reset()     {         Current = () => new HttpContextWrapper(HttpContext.Current);     } } 

Nothing particularly fancy. And it works just fine in our controller code. The kicker came when we go to write unit tests. We're using Moq as our mocking framework, but alas

var context = new Mock<HttpContextWrapper>()  

breaks since HttpContextWrapper doesn't have a parameterless ctor. And what does it take as a ctor parameter? A HttpContext object. So I find myself in a catch 22.

I'm using the prescribed way to decouple HttpContext--but I can't mock a value in because the original HttpContext object was sealed and therefore difficult to test. I can map HttpContextBase, which both derive from--but that doesn't really get me what I'm after. Am I just missing the point somewhere with regard to HttpContextWrapper?

Edit to clarify intent

We found ways to solve the problem--but I guess the ultimate question we're walking away with is what value HttpContextWrapper brings to the table? I don't doubt somewhere someone totally had an a-ha! moment with it, but it just doesn't come to me. Most postings I see here discuss it in terms of testability--but my own experience has led me to believe that it didn't bring much in that context. Unless we're doing it wrong. (Wholly possible).

like image 391
bakasan Avatar asked Mar 09 '10 08:03

bakasan


People also ask

What is HttpContextWrapper?

The HttpContextWrapper class derives from the HttpContextBase class and serves as a wrapper for the HttpContext class. This class exposes the functionality of the HttpContext class and also exposes the HttpContextBase type.

What is HttpContextBase?

The HttpContextBase class is an abstract class that contains the same members as the HttpContext class. The HttpContextBase class enables you to create derived classes that are like the HttpContext class, but that you can customize and that work outside the ASP.NET pipeline.

How can get HttpContext current in asp net core?

In ASP.NET Core, if we need to access the HttpContext in service, we can do so with the help of IHttpContextAccessor interface and its default implementation of HttpContextAccessor. It's only necessary to add this dependency if we want to access HttpContext in service.


1 Answers

This blog post explains it pretty well:

http://splinter.com.au/httpcontext-vs-httpcontextbase-vs-httpcontext

The point is that 'vintage' HttpContext does not implement HttpContextBase, and isn't virtual, and therefore cannot be Mocked. HttpContextBase was introduced in 3.5 as a mockable alternative. But there's still the problem that vintage HttpContext doesn't implement HttpContextBase.

So HttpContextWrapper is a handy wrapper class (or 'kludge') that does implement HttpContextBase, and can be used when injecting a 'real' HttpContext using IOC, usually with a factory method like this: () => new HttpContextWrapper(HttpContext.Current)

like image 103
codeulike Avatar answered Sep 21 '22 19:09

codeulike