Adding an Interceptor to existing Castle.DynamicProxy proxy - c#

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.

Related

How do you test that a new instance of an object has been created?

I'm using C#, xUnit, and Moq for unit testing. I have an object with a property of a complex type. To "clear" the property and all its properties, I do this:
this.ComplexTypeInstance = new ComplexType();
Now I'm trying to assert that ComplexTypeInstance has been assigned to a brand new object. My first thought was to compare ComplexTypeInstance to new ComplexType() and see if they are equal. But to do something like that I think I'd have to override the equals operator. Is there any way to easily check that all properties are set to their defaults? Or is there a way to assert that I've newed up the object?
Or is there a way to assert that I've newed up the object?
Just compare the references between the old one and the new one using ReferenceEquals. If they are different, then the property has been replaced.
var origInstance = this.ComplexInstance;
... // Some operation
Assert.False(object.ReferenceEquals(this.ComplexInstance, origInstance));
After thinking about this a bit, there were a few different scenarios I came up with to make it easier to test:
Wrap the ComplexType in a factory sort of method. I didn't like this b/c it just means one more class to create, and I wanted to avoid having such a simple factory.
Extract and Override - Create a virtual method that allows me to remove the concrete dependency. Google "Extract and Override" if you have questions. I don't like this b/c if you don't know the technique it can seem weird.
Inject an anonymous function that returns a new instance of the object.
A co-worker mentioned I could have also used Mark Seeman's SemanticComparison to compare my property to a new object.
I ended up going with the third option, injecting it through the constructor, though my IOC container couldn't resolve it easily and I had to spend a couple minutes trying to get it to resolve a binding for it. But I got it working pretty well. Maybe I should have just created the factory. But I'm glad I took out the dependency from the class. At first I didn't want to b/c it seemed so simple.

Simple Injector change registration at runtime

I'm using Simple Injector with an ASP.NET Web API project, and I want to use different implementations for one interface, depending on the version of REST endpoint used. For example, if v1 of an endpoint is used, IPaymentData should be instantiated with a class called PaymentData, but if v2 is used IPaymentData should be implemented by a class called PaymentDataNew. This is turning out to be problematic!
I don't want to use a composite class like a part of Simple Injector documentation suggests since that means that my code needs to be aware of and take into account the injection framework I'm using (bad).
I noticed in the latest version (3.0) that something called "Context based injection" is a feature. Using the container.RegisterConditional function it should be possible to run a delegate each time a type is resolved.
container.RegisterConditional(typeof(IPaymentData),
c => ((HttpContext.Current.Items["version"] as string ?? "1") == "2")
? typeof(PaymentDataNew)
: typeof(PaymentData),
Lifestyle.Scoped,
c => true);
This doesn't seem to work, though, since even though the lifetime is scoped, and the default lifestyle is WebApiRequestLifestyle the delegate which returns the implementation depending on version is only called for the first request that comes in. Subsequent requests skip this (they seem to be using a cached implementation).
Is there something I'm missing? How can I make sure the delegate is called each time a request comes in??
since that means that my code needs to be aware of and take into account the injection framework I'm using
Not exactly. The composite pattern is a well known and commonly used pattern, so defining it in your code doesn't make your code dependent on the DI library. And if you don't want to define the composite in your application code, you can always specify it inside your Composition Root. The Composition Root already has a very strong dependency on the DI library, so any library-specific stuff should be placed there.
Using the container.RegisterConditional function it should be possible to run a delegate each time a type is resolved.
Simple Injector v3's RegisterConditional method allows applying registrations conditionally based on static information. This means that the supplied predicate is only called a finite amount of time (usually once per consuming component). The methods (IntelliSense/XML) documentation states:
The predicate will only be evaluated a finite number of times; the predicate is unsuited for making decisions based on runtime conditions.
It will not be called every time you resolve it. The reason for this is two-fold:
This optimizes performance, because the decision made in the predicate can be burned into the compiled expression, but more importantly,
This prevents you from making runtime decisions during the building of the object graph.
The shape of your object graph should not be dependent on runtime parameters (such as the version in your HttpContext). Doing this complicates the object graph and makes it very hard to verify and diagnose the object graph for correctness.
The solution I would advice is to implement a proxy implementation for IPaymentData that allows making the switch at runtime. This is not a Simple Injector specific implementation; you should strive to have simple, static, and verifiable object graphs, independently of the DI library you use.
This is how such proxy might look like:
public sealed class HttpRequestVersionSelectorPaymentData : IPaymentData
{
private readonly PaymentData paymentOld;
private readonly PaymentDataNew paymentNew;
public VersionSelectorPaymentData(PaymentData old, PaymentDataNew paymentNew) { ... }
private bool New => HttpContext.Current.Items["version"] as string ?? "1") == "2";
private IPaymentData PaymentData => this.New ? paymentNew : paymentOld;
// IPaymentData method(s)
public Payment GetData(int id) => this.PaymentData.GetData(id);
}
Although it is absolutely possible to make runtime decisions during the building of the object graph (by registering a delegate), I strongly advice against doing this, for the reasons expressed above.

Mock NHibernate IQueryOverOrderBuilder object

So I'm trying to write some test cases for my business logic layer. I've already mocked up my data access layer (which returns NHibernate IQueryOver objects). I created a MockQueryOver class that implements the IQueryOver interface because I chain functions in the business logic layer so creating a stubbed IQueryOver didn't make sense to me.
Anyway, that all works, but the problem I'm having is when I try to do an OrderBy() on the QueryOver. In my MockQueryOver class, I implement the OrderBy() method like this right now:
public IQueryOverOrderBuilder<TRoot, TSubType> OrderBy(Expression<Func<TSubType, object>> path)
{
var func = path.Compile();
IList<TSubType> result = m_data.OrderBy(func).ToList();
var mockRepo = new MockRepository();
var queryOver = new MockQueryOver<TRoot, TSubType>(m_data);
IQueryOverOrderBuilder<TRoot, TSubType> mockOrderBuilder = mockRepo.StrictMock<IQueryOverOrderBuilder<TRoot, TSubType>>(queryOver, path);
mockOrderBuilder.Stub(x => x.Desc).Return(queryOver);
mockOrderBuilder.Stub(x => x.Asc).Return(queryOver);
return mockOrderBuilder;
}
The problem is that RhinoMocks throws an exception on any of the Stub methods. This is the exception:
System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Criterion.Lambda.QueryOverOrderBuilderBase`3.AddOrder(Func`2 orderStringDelegate, Func`2 orderDelegate)
at NHibernate.Criterion.Lambda.QueryOverOrderBuilderBase`3.get_Desc()
at NHibernate.Criterion.QueryOverBuilderExtensions.Desc(IQueryOverOrderBuilder`2 builder)
at BLL.Tests.Mock_Objects.MockQueryOver`2.<OrderBy>b__7(IQueryOverOrderBuilder`2 x) in MockQueryOverSubType.cs: line 239
I'm new to NHibernate and RhinoMocks, so I'm not sure what it's doing behind the scenes, but it seems like even though I'm creating a mock of an interface, it still calls concrete extension methods when I try to stub a method.
Can someone please clarify this or help me out with this problem? Also, since I'm just beginning to write these test cases, I don't mind switching mocking frameworks, as long as it's free to use.
Thanks a lot!
Are you certain IQueryOverOrderBuilder is an interface? It seems to be a confusingly-named class that implements QueryOverOrderBuilderBase. I'm not entirely sure what the behaviour is in this situation, but I think your StrictMock of IQueryOverOrderBuilder is actually calling through to that base class, which probably isn't set up, and is throwing the exception you're seeing.
I think that perhaps you might need add another abstraction layer in between your business logic and NHibernate, with classes that you can reliably mock. I don't think there's a way of mocking a concrete class like IQueryOverOrderBuilder with RhinoMocks (but I'm happy to be corrected if there is :).
To create another abstraction layer, analyse the operations in your business logic that currently interact with NHibernate, and define a new interface of functions to encapsulate those operations (say, IRepository). Code that adds something to the database through NHibernate might become a function on the interface named AddItem. Move the code that interacts with NHibernate behind this interface into new functions on a new class (there's no reason why it needs to be a single class - you could group logically-related code into separate classes with separate interfaces). The new interface might be able to reference some NHibernate classes and interfaces that can be easily instantiated or mocked, respectively (ideally, the interface wouldn't reference NHibernate at all, but you're doing this for testing, not to fully decouple your code from NHibernate, so it's fine). Once you've done this, your business logic can be unit-tested against a mock (or mocks) of the new interface, and the class or classes that implement that interface can be integration tested against an actual database. This is, loosely, the Adapter pattern. Without seeing exactly what your business logic does, it's difficult to comment further on the design. I hope this is helpful.
Finally, if you're creating your own MockRepository, I think you need to call Replay() on the mocks you create (or ReplayAll() on the MockRepository) after you stub them. You don't need to do this if you create your mocks from the static methods on MockRepository. Seems unrelated to your current issue (although, try calling it after your Stub calls and see if it makes any difference), but I thought I'd mention it anyway.

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

Create an InterfaceProxyWithoutTarget with a default constructor

Using Castle.DynamicProxy, I "simply" would like to get an Interface-Proxy-Without-Target, but... With a default-constructor so I be able to reuse the proxy-type.
UPDATE
I mean doing something like...
var proxy = generator.CreateInterfaceProxyWithoutTarget(typeof(TInterface) ...);
var proxyType = proxy.GetType();
var newproxy = Activator.CreateInstance(proxyType);
...Except that generated type do not implement default-constructor.
My actual context is related to WCF customization, but that's another story.
no, it does not work that way
when you call CreateFooProxy method on proxy generator, your proxy type WILL be reused as long as it is possible. See here for details if you're interested.
If you're doing some kind of WCF customization based on DynamicProxy you might want to check Castle WCF Facility. It uses DynamicProxy and has some very cool capabilities.

Categories

Resources