Is HttpContextWrapper all that....useful? - c#

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).

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)

You should be using the abstract HttpContextBase which is much easier to mock instead of HttpContextWrapper.
public static Func<HttpContextBase> Current =
() => new HttpContextWrapper(HttpContext.Current);
And in your unit test:
SomeClass.Current = MockHttpContextBase(); // Sorry I don't know the syntax for Moq

One real world example other than testing.
Besides mocking I stumbled upon a peculiar issue that the wrapper class really helped me solve. We have an application in Azure and we have control only on the application. It sits behind a reverse proxy which changes the host header of the incoming requests and sends the original host in a custom header. The application relies on the host header in order to build dynamic links, validate redirects etc. so we needed a way to substitute the host that was set in the HttpContext.HttpRequests.Url property. Since we exposed the HttpContext only as HttpContextBaase using the wrapper everywhere in the app we were able to create a class that inherits HttpContextWrapper and overrides the Request and then returns object that inherits from the RequestWrapper and overrides the Url property. So in the end the application replaced the host in the url that ASP.NET used for the context with the custom host from the custom header the reverse proxy has set. There was no other way from within the app to do that other than manually searching through the code where HttpContext.Request.Url is used and applying fix.

Related

Adding an Interceptor to existing Castle.DynamicProxy proxy

Let's say I have a Castle.DynamicProxy object that is created by a third party. In this case Rhino.Mocks.
var rhinoObj = MockRepository.GenerateMock<IMyType>();
For one reason or another I want to be able to use this generated object by Rhino and add another interceptor to it so I can manipulate it without using Rhino itself.
I understand this may seem weird, its for a mocking library I'm writing myself that I want integrated with other mocking frameworks that use Castle, such as Rhino.
I have tried:
generator.CreateInterfaceProxyWithTarget(rhinoObj, new MyInterceptor())
But Rhino complains when I wish to use anything such as .Stub(..) that this is not a mocked object - so clearly the rhino interceptors are overwritten.
I know it is an old question but I had the same problem. Reading my own answer 2 days ago would have saved me several hours...
The Problem
Rhino.Mocks with the help of castle dynamic proxy generates a new type based on your interface, creates an instance of it and returns it to you. This instance is also used as a rhino.mock-internal key to look up all mocking-things (assertions, return values, ...).
Now you create a proxy (means: another new type and another new instance) around the rhino.mock-object and the lookup-by-instance does not work anymore. You need the original object somehow.
Option 1
You need to keep the original object from rhino.mocks around. How this will look depends on your overall setup. Maybe all instances creation goes through a central repository and you can add handy accessor methods like those:
internal interface IMockRepository
{
void Add(object key, object mock);
T GetMock<T>(T key);
object GetMock(object key);
}
This should the trick any mocking framework, not just rhino.mocks. On the minus-side is extra infrastructure and boilerplate code. And the akward feeling that you create a proxy around a proxy.
Option 2
(based on this answer): Rhino.mocks also uses castle dynamic proxies and interceptors. Maybe we can sneak in our own interceptor? We can!
var mock = Rhino.Mocks.MockRepository.GenerateStub(type);
dynamic dyn = mock;
dyn.__interceptors = new[] {new MyInterceptor(), dyn.__interceptors[0]};
You need to use IInterceptor and IInvocation from Castle.Core.Interceptor instead of Castle.DynamicProxy but the interfaces are identical. The original proxy must come last.
This relies on rhino.mocks-internals which might change in any future release without notice. But I think it is save to assume that (a) rhino.mocks will continue to use castle dynamic proxies and (b) dynamic proxies will be dynamics also in future. So if something breaks, it should be fixable.
This is more "hacky" but I use this solution. No "proxy-of-proxy"-thing and no boilerplate.

Can I mock a private method or what is the correct way to test this POST method?

I have an existing ASP.NET MVC app and wanted to create some unit tests and I quickly ran into the problem below. Is there some sort of way to use MOQ and say 'When the private method GETCLIENTIP is run then return 'xxx'')?
Since right now it is uses parts of HttpContext that of course the unit test does not have.
public HttpResponseMessage Post([FromBody]TriageCase TriageCase)
{
if (ModelState.IsValid)
{
//Get the IP address from the request
TriageCase.ipAddress = this.GetClientIP(Request);
_log.Info("IP Address = " + TriageCase.ipAddress);
}
}
public void Verify_Not_A_Suicide()
{
TriageCaseRepository repository = new TriageCaseRepository();
var controller = new TriageCasesController(repository);
//This will not work because I must mock a private method in the controller?
HttpResponseMessage result = controller.Post(new TriageCase());
}
There are several ways to do this, right from nasty complicated ones to simple traded-off ones. here are some:
you could make the GetClientIP method agnostic of HttpContext. and then make it internal. mark the controller assembly with InternalsVisibleTo and put the unit test assembly path.
making the method agnostic of HttpContext saves you from having a HttpContextBase (the abstract http context class from 3.5 onwards for to enable testing) and provide mocking etc. (btw, you should think about it. especially for MVC) pass the specific string as the parameter to the method. e.g. The specific server variable string.
you could make the GetClientIP method receive HttpContextBase as the parameter and then make it internal. mark the controller assembly with InternalsVisibleTo and put the unit test assembly path.
in your controller action, you need to call this method as this.GetClientIP(new HttpContextWrapper(HttpContext.Current))
your unit tests can set mockable context. and whats more, you can set expectations on the context as to if the Request property was called, or if the ip address related server variable call was made. (not to mention the straight ip address value verification)
you could use FakeItEasy or Microsoft Moles etc. to create private accessors for private methods. i normally refrain from that.
you could write an interface base INetworkUtility which has a method to give you the IP Address. your controller could use this interface. and it could be tested in isolation as well.
you could have a public helper class to get the ip address, which can be unit tested.
as you can see, every solution has some trade-off you need to do.
getting IP Address from the Request object is an isolated piece of logic irrespective of mvc or web api or asp web forms. (still web specific though) so it doesn't harm to have it as helper methods or interface based helper methods.
personally, i prefer the Internal approach, (since it is almost private) and doesn't need much code change.
In proper TDD fashion you don't Unit Test "private" or "internal" methods. Only the public interface is used within Unit Tests. If you Unit Test a private/internal method then you are tying your unit tests too tightly to that specific implementation.
What should be done instead is use Dependency Injection to inject a class/interface that implements the "dependent" functionality that you are needing to unit test. This will help further modularize your code thus making it easier to maintain.
I general don't try to test private methods. It just gets messy - test the input and output of an action...
Either do the Dependency Injection thing or think about a "test double" or "accessor" class...
For a test double - make the private method a protected and then you inherit the controller and manually mock out inputs or outputs as required. I am not stating whether this is better or worse than Ioc, I am saying this is another way to do it.
protected virtual string ExecuteIpnResponse(string url)
{
var ipnClient = new WebClient();
var ipnResponse = ipnClient.DownloadString(url);
return ipnResponse;
}
I did a post on this testing style recently for checking a paypal call.
http://viridissoftware.wordpress.com/2014/07/29/paypal-ipn-payment-notification-example-in-c/

Attempt to resolve item from Ninject in IInterceptor fails

I am attempting to use Ninject on my current project, and up to now, have been loving it. I am in the middle of attempting to configure an IInterceptor object to intercept and handle a failed method call to my service layer. This is hosted in an ASP.NET MVC 5 application.
In the IInterceptor, I've tried several things, such as:
Setting private variables using constructor injection, but came to discover that it appears Ninject will reuse an IInterceptor instance for a method indefinitely, and I haven't found a way to stop that. Since one of the things I bring into scope is a DbContext which gets disposed elsewhere, it ends up failing on any future requests than the one it was created on.
I found that the IInvocation has a Request.Kernel property. However, when I attempt to resolve my UOW from the container, which is .InRequestScope(), it fails, since it attempts to resolve the IUowService dependencies, (one of the dependencies depends on the HttpContext which is null at this point), but appears to be doing so outside the Request scope. It is ignoring the fact that the dependencies it needs have already been created within the ASP.NET request, and is attempting to create new ones.
Setting a binding for the interceptor this.Bind<NinjectExceptionHandler>().ToSelf().InTransientScope(), yet this didn't seem to stop the caching of the interceptor.
I imagine there is something I am missing. I understand wanting to cache IInterceptor objects for performance, but I find it irksome that I can't easily use the IOC container or Injection to get the objects I need for my request.
This is the last issue I am having with getting interception up and running as I need, so any help is greatly appreciated!
Per your request i'm going into more detail on how we've achieved "1 proxy : 1 interceptor" instance relation ship.
We've taken the easy way which does not offer as much flexibility as what the official ninject interception extensions offers. We are relying directly on castle.core dynamic proxy and thus castle's IInvocation interface.
(Please not the code below is for a proxy without target, but a proxy with target is quite similar -- the only thing which changes is that you'll need to know the target class type and use IResolutionRoot.Get<TargetClassType>() to instanciate it).
Basically we created a binding like:
IBindingRoot.Bind<IFoo>()
.ToProvider<InterfaceProxyWithoutTargetProvider<IFoo>>();
Now of course we need to know which interceptors the proxy shall use. Again we are using an easy - and not so nice - design:
public interface IInterceptorBindingDefinition<TTarget>
{
Type InterceptorType { get; }
}
public class InterceptorBindingDefinition<TTarget, TInterceptor> : IInterceptorBindingDefinition<TTarget>
where TInterceptor : IInterceptor
{
Type InterceptorType { get { return typeof(TInterceptor); } }
}
IBindingRoot
.Bind<IInterceptorBindingDefinition<IFoo>>()
.To<InterceptorBindingDefinition<TTarget, LoggingInterceptor>();
IBindingRoot
.Bind<IInterceptorBindingDefinition<IFoo>>()
.To<InterceptorBindingDefinition<TTarget, SomeOtherInterceptor>();
This means IFoo shall get two interceptors: LoggingInterceptor and SomeOtherInterceptor.
and the implementation of the provider:
public class InterfaceProxyWithoutTargetProvider<TInterface> : IProvider<TInterface>
where TInterface : class
{
private readonly IProxyGenerator proxyGenerator;
private readonly IInterceptorFactory interceptorFactory;
public InterfaceProxyWithoutTargetProvider(IProxyGenerator proxyGenerator, IInterceptorFactory interceptorFactory)
{
this.proxyGenerator = proxyGenerator;
this.interceptorFactory = interceptorFactory;
}
public Type Type
{
get { return typeof(TInterface); }
}
public object Create(IContext context)
{
var interceptorTypes = context.Kernel.Get<IEnumerable<IInterceptorBindingDefinition<TInterface>>();
IList<IInterceptor> interceptors = interceptorTypes
.Select(x => x.InterceptorType)
.Select(x => context.ContextPreservingGet(x))
.ToList();
return this.proxyGenerator.CreateInterfaceProxyWithoutTarget<TInterface>(interceptors);
}
}
Now of course we polished the thing a little bit so we have a fluent syntax configuring the binding of the proxy and the interceptor - which is easy enough.
However ninject.extensions.interception's approach with its IAdviceRegistry and IAdvice is certainly better (but also requires more insight into how ninject works).
So it appears that there is no way to do what I was trying gracefully with Ninject. Once in the IInterceptor and in the later parts of async operations, the HttpContext was lost and Ninject couldn't resolve things that really it should have thought were in scope. Coupled with the fact that it reused IInterceptor's for a method (like I said, understandable, but irritating), I just couldn't get it to work right as I wanted to.
What I was able to do to get around the fact was something simple, yet a little kludgy (I think). Since all the methods that I was intercepting were in my service layer, and all my services implemented a IBaseService through a BaseService abstract base class, which happened to have the objects I needed as properties, I was able to do this in the interceptor:
var uow = (invocation.Request.Target as IBaseService).UnitOfWork;
This allowed me to access my unit of work and Fail it, as well as access the logging instance I was working on.
While this works, I would like to see someway to get interceptor constructor injection working correctly through multiple calls, or calls to the Kernel further down the line to realize that it has already resolved an object still in scope (although I am guessing that it may think its out of scope since ASP.Net abandoned the scope upon await).
For any interested, I am going to try and post about this on my blog soon (see my user page if actually interested, not spamming SO myself).

Unit testing with dependency on HttpContext

I need to test some static methods that rely on the current context. Now, I can certainly use the HttpContextWrapper to remove this dependency from my own code. The problem lies with the 3rd party API I am using in these methods. THEY are relying on the HttpContext and so I can't do anything about that. However, what I'm trying to do is set the HttpContext with my HttpContextBase.
So my code looks something like this:
public static bool IsSignedUpUser()
{
//This calls IsSignedUpUser with the production context
return IsSignedUpUser(new HttpContextWrapper(HttpContext.Current));
}
public static bool IsSignedUpUser(HttpContextBase context)
{
HttpCookie objCookie = SomeExternalAPIThatReliesOnHttpContextBeingSet();
return (objCookie != null)
}
What I want to do is something like:
HttpContext.Current = context; //where context is a mocked HttpContextBase
This way when the 3rd party API is looking in the HttpContext for querystring, cookie values, etc, it doesn't throw a NullReferenceException.
Why isn't this a dupe?
In the code in the question referenced as a dupe, the author looks to be in complete control with no external dependencies. I'm using third party libraries that have a dependency on HttpContext, I can't change their method signatures to accept HttpContextBase so I need a way to assign my HttpContextBase to HttpContext.
If this is not possible, and so far I am lead to believe that it isn't, then good answers should suggest how to remove these dependencies. 500 - Internal Server Error has at least one good suggestion.
In my view, you should be replacing the call to SomeExternalAPIThatReliesOnHttpContextBeingSet with a custom interface method that you inject and which can then be mocked as any other.
[EDIT] Per #jessehouwing, "Moles" is now "Fakes", which should improve your Google-fu
Ah, static dependencies...the worse kind.
It may be overkill, but I would look into perhaps using Moles (or whatever the heck they renamed it to), which will let you override ANY behavior, static, sealed or otherwise; here are some links to peruse:
Mocking the Unmockable
The Moles Framework
Unit Testing with Moles
A different "Mocking the Unmockable"

Dependency Injection Optional Parameters

Is it considered a bad practice to use optional parameters when using dependency injection frameworks with Constructor injection?
Example:
public class ProductsController
{
public ProductsController(IProductService productService = null, IBackOrderService = null)
{
}
}
I have specified both parameters as optional, but my DI framework will always inject both dependencies. If I add a new action to my controller which requires a new dependency, would it be bad to make the new dependency optional? I could potentially be breaking dozens of unit tests even though the existing tests wouldn't require the new dependency.
Edit
People seem to be confused by my question. I am never construcing a ProductsController manually in my web application. This is handled by a controller factory (which automatically injects dependencies).
What I don't like is having a unit test like this:
[Test]
public void Test1()
{
var controller = new ProductsController(new MockProductService(), new MockBackOrderService());
}
Now I decide to add a new action method to my controller. This new action needs a new dependency but none of the existing actions do. Now I have to go back and modify 100 different unit tests because I added a new parameter. I can avoid that by making the parameters optional, but I wanted to know if it was a bad idea. My gut feeling says no because the only thing it affects are the unit tests.
I completely agree with the accepted answer for all the cases on that defining a Dependency means that implementation will not work with out it.
But what if you have something that does not necessarily need a dependency but you want to be able to configure something if that dependency has been loaded. OK...? that sounds a bit weird but its a valid Meta Programming use case - and you think maybe factory pattern could help.. but even the factory may need some, none or all dependencies so Factory does not solve this problem.
Real world problem of feature flags. If a feature is turned off you
don't need that dependency.. or maybe cant even create it because
there is no concrete implementation. So its turned off. It compiles,
everything works OK. But then somebody switches the feature on and all
of a sudden we need that dependency.
I found a way to do this -- and the best part is I only realised how to do this by learning about another not so well known technique with Dependency Injection (I am using Microsoft.Extensions.DependencyInjection)
Injecting several concrete implementations for a single Interface
services.AddTransient<IWarehouseRepo, ActionRepository>();
services.AddTransient<IWarehouseRepo, EventRepository>();
services.AddTransient<IWarehouseRepo, AuditRepository>();
services.AddTransient<IWarehouseRepo, ProRepository>();
services.AddTransient<IWarehouseRepo, SuperWarehouseRepository>();
services.AddTransient<IWarehouseRepo, InferiorWarehouseRepository>();
services.AddTransient<IWarehouseRepo, MonthlyStatisticsRepository>();
I only learnt recently that this is completely valid but for this to work your constructor needs to look like this..
public WarehouseHandler(IEnumerable<IWarehouseRepo> repos)
So that is super cool! I can select a repository I need based on whatever criteria. But how does this help with Optional Dependencies?
Because this type of constructor will give you 0 or more dependencies. So if you do not add any dependencies you can branch out in the constructor using a conditional statement
if (repos.Count() == 0)
return;
This is null reference safe, does not require default values, easy to debug, easy to read and easy to implement.
You can now also use this technique as the feature switch mechanism too!
I don't think it's a good idea. Constructor injection means that the dependencies are required. You should even add the guard lines that throws if one of the parameters is null.
I think the problem is with your unit tests. For instance I have only one place where the controller is created and supporting objects are mocked (controllerContext, HttpContext, Request, Response, etc.). Then if I add a new parameter in the constructor I have to change it only in one place in the unit tests.
Maybe you should consider to code a generic base class in your unit tests, or make a usage of "setup" routine for the tests.
Consider to use The Test Data Builder pattern.
In the simplest form it could be done as static test helper method
public ProductsController BuildControllerWIthMockDependencies ()
{
var controller = new ProductsController(new MockProductService(), new MockBackOrderService());
return controller;
}
You can use AutoFixture as a generic Test Data Builder.
Further techniques for using Test Data Builders can be found in Test Data Builders: an alternative to the Object Mother pattern

Categories

Resources