Let's say we have integration test with extensive configuration IConfiguration
. I've setup the test to work with autofac containers, and now I'd like to use Mock to replace the operation on one of it's properties without the need to mock or replace everything else:
var config = MyTestContainer.Resolve<IConfiguration>();
//let's say that config.UseFeatureX = false;
//here, I'd like to create mock "around" the existing instance:
var mockedConfig = Mock.CreateWith(config); //CreateWith => a method I'd like to find how to do
mockedConfig.Setup(c => c.UseFeatureX).Returns(true);
How to do this wrapping around existing instance? It should be similar to .CallBase
but instead of just calling base implementation, I was hoping there would be a way to call base values.
I believe by default
Moq
allows you to pass constructor parameters forIConfiguration
implementation and it will make a new instance of that class for you for you. If I understand your problem correctly you want to rather use a pre-constructed instance. I assume you are aware ofCallBase
and it does not quite do what you need.So basically, the following snippet illustrates the issue:
now, knowing that
Moq
internally leverages Castle DynamicProxy and it actually allows us to generate proxies for instances (they call it Class proxy with target). Therefore the question is - how do we getMoq
to make one for us. It seems there's no such option out of the box, and simply injecting the override didn't quite go well as there's not much inversion of control inside the library and most of the types and properties are marked asinternal
, making inheritance virtually impossible.Castle Proxy
is however much more user firendly and has quite a few methods exposed and available for overriding. So let us define aProxyGenerator
class that would take the methodMoq
calls and add required functionality to it (just compareCreateClassProxyWithTarget
andCreateClassProxy
implementations - they are almost identical!)MyProxyGenerator.cs
if all of the above was relativaly straightforward, actually feeding it into
Moq
is going to be somewhat of a hack. As I mentioned, most of the structures are markedinternal
so we'll have to use reflection to get through:MyMock.cs
given we've got the above working, the actual solution would look like so:
hopefully this helps.