We have a test projects that runs as expected on AutoFixture v3.51 but, to write better tests in some situations (and to start moving to an up to date version), we move to 4.2.1 but multiple tests started to crash (after renaming from Ploeh.AutoFixture
to AutoFixture
, obviously). I then rolledback to 4.0.0 with the same result.
The documentation is quite clear on how to fix the problem using a TypeRelay
but my question is about the why more than the how. I read the release notes 3 times but I can't find anything that would explain this change in behaviour.
Moreover, not knowing why this happens now, I can't figure out precisely on which object's properties branch the problem is occuring and see if something could be done differently.
The exact message was:
AutoFixture.ObjectCreationExceptionWithPath:AutoFixture was unable to create an instance from System.Collections.IEnumerable because it's an interface. There's no single, most appropriate way to create an object implementing the interface, but you can help AutoFixture figure it out.
As explained with more detail in the GitHub discussion, the problem came from my Init method that was customizing my Fixture.
_fixture.Customize<ListeCommunicationModel>(x => x
.With(y => y.SortingProperties, (System.Web.Mvc.SelectList) null));
before using the Fixture.Build
method in my test. This change came with Pull Request #781 that released with v4 and that now ensures that Fixture.Build
starts on a clean slate and ignores any Customize
done to the AutoFixture
instance.
For my code, based on the recommendation from aivascu, I created a simple generic extension method and some private methods in classes getting converted to AutoFixture v4. It is clearly not as reusable as the original proposition but felt more adequate for my situation.
public static class AutoFixtureExtensions
{
public static IPostprocessComposer<T> ApplyDefaults<T>(this IPostprocessComposer<T> actual, Func<IPostprocessComposer<T>, IPostprocessComposer<T>> composer)
{
return composer(actual);
}
}
[TestClass]
public MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
var myInstance = _fixture.Build<InstanceType>()
.ApplyDefaults(DefaultIntanceType)
}
private IPostprocessComposer<InstanceType> DefaultIntanceType(IPostprocessComposer<InstanceType> src)
{
return src
.With(x => x.MyProp1, new List<object>())
.With(x => x.MyProp2, (SelectList)null!);
}
}