Suggested solution
To start with a possible solution, this should stop the crashing:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
// This should fix the problem for all Controllers
fixture.Customize<ViewDataDictionary>(c =>
c.Without(x => x.ModelMetadata));
HomeController controller = fixture.CreateAnonymous<HomeController>();
Explanation
And now for the explanation:
This test error is caused by AutoFixture's AutoProperties feature trying to assign a value to HomeController.ViewData.ModelMetaData
. The ModelMetaData class has this constructor:
public ModelMetadata(
ModelMetadataProvider provider,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
The culprit here is the modelAccessor
parameter. To fill that property AutoFixture (rather mindlessly) reflects over the type and finds this single constructor:
public Func(object @object, IntPtr method)
Digging further, the first IntPtr constructor AutoFixture can satisfy is this one:
public unsafe IntPtr(int value)
By default, Int32 instances are created by a deterministic rising sequence, so value
in this case will probably be 1 or 2 or a similar small integer. In other words, we now have a very invalid unsafe pointer on our hands, and this is making the process crash.
Now, under normal circumstances we should be able to fix this by registering a Func<object>
with the Fixture and everything should be dandy:
fixture.Register<Func<object>>(() => () => new object());
However, I tried this with your repro and although the process no longer crashes in the same way, the test runs for a very long time and finally crashes with an OutOfMemoryException.
I don't know what ASP.NET MVC does with Func<object>
, but apparently it uses it quite heaviliy.
The question remains whether this is a bug in AutoFixture?
I believe that it isn't. While it is definitely less than ideal, AutoFixture doesn't treat Funcs or Actions any differently than other types, which is why we see this behavior.
This particular behavior could possibly be addressed by adding specific support for Func<TResult>
, but to stay consistent it should also have support for Func<T, TResult>
, Func<T1, T2, TResult>
, etc. AFAIR in .NET 4 there are a lot of these delegate types (also Action, etc.), so that would mean adding support for a whole host of types.
But then what about all other types that take an IntPtr in their constructor? AutoFixture can't possibly know about them all, so this seems not like a viable direction.
However, what it could have is a guard that prevents it from attempting to create IntPtr instances in the first place. This will most likely be added before the 2.0 RTW.
Thank you for reporting this.