Mocking Autofac "Resolve" extension method with TypeMock
I am trying to poke fun at Autofac's solution like
using System;
using Autofac;
using TypeMock.ArrangeActAssert;
class Program
{
static void Main(string[] args)
{
var inst = Isolate.Fake.Instance<IContainer>();
Isolate.Fake.StaticMethods(typeof(ResolutionExtensions), Members.ReturnNulls);
Isolate.WhenCalled(() => inst.Resolve<IRubber>()).WillReturn(new BubbleGum());
Console.Out.WriteLine(inst.Resolve<IRubber>());
}
}
public interface IRubber
{}
public class BubbleGum : IRubber
{}
Coming from Moq, the syntax and exceptions from TypeMock confuse me a lot. Initially running this in TestMethod, I kept getting an exception like "WhenCalled could not be started without additional behavior". I've tried defining behavior for everyone and their mothers, to no avail.
Then I debugged by going through a test run and saw that the actual exception was being thrown from Autofac: IRubber was not logged.
So, obviously, the static Resolve function is not faked, and I cannot fake it, no matter how I go about hooking it up.
Isolate.WhenCalled(() => ResolutionExtensions.Resolve<IRubber>(null)).WillReturn(new BubbleGum());
... throws an exception from Autofac complaining that the IComponentContext cannot be null. Submitting it to a supposedly bogus IContainer (or bogus IComponentContext) brings me back to the "IRubber not registered" error.
a source to share
This could be one of those up-and-coming floats - the amount of code required to create a "real" container, with a corresponding dependency registered, is less or similar to the configuration for TypeMock. I would suggest going down this path.
Instead of making the target component depend on IContainer at all, you could instead use Relationship Types such as Func, which are implicitly supported by Autofac and are more expressive, in addition to light mocking. http://nblumhardt.com/2010/01/the-relationship-zoo/ has more information on this approach as well as http://code.google.com/p/autofac/wiki/DelegateFactories .
a source to share