I have a custom specimen builder for AutoFixture that omits requests for anonymous values in properties based on the type of the property being requested.
public class PropertyTypeExclusion<T> : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var propertyInfo = request as PropertyInfo;
if (propertyInfo?.PropertyType == typeof(T))
{
return new OmitSpecimen();
}
return new NoSpecimen();
}
}
I can add the customization to the fixture no problem, and it works as expected.
_fixture.Customizations.Add(new PropertyTypeExclusion<IdentityRef>());
Now I want this exclusion to be registered to requests for a specific type. Something like this:
_fixture.Customize<Release>(c => new PropertyTypeExclusion<IdentityRef>());
While the use of .Customize<Release>
is valid, it has the same outcome as the call to .Customizations.Add
.
Is there a way to register this ISpecimenBuilder
only to a specific requested type?
If I understand you correctly, you'd like to be able to do smth like this:
fixture.Create<Release>(); // the `IdentityRef` prop is omitted
fixture.Create<SomeOtherType>(); // the `IdentityRef` prop is NOT omitted
Ok, let's look on this statement:
While the use of .Customize is valid, it has the same outcome as the call to .Customizations.Add
... meaning that even if you register the customization for the Release
type only, the other types are impacted as well:
fixture.Customize<Release>(c => new PropertyTypeExclusion<IdentityRef>());
fixture.Create<Release>(); // the `IdentityRef` prop is omitted which is OK
fixture.Create<SomeOtherType>(); // the `IdentityRef` prop is also omitted but it MUST NOT
That sounds like a bug in AF to me and I'd address it here...
As a quick workaround to your issue, you can extend the customization to accept both class and property types to perform more precise filtering:
public class PropertyTypeExclusion<TType, TProp> : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var propertyInfo = request as PropertyInfo;
if (propertyInfo?.PropertyType == typeof(TProp) &&
propertyInfo.DeclaringType == typeof(TType))
{
return new OmitSpecimen();
}
return new NoSpecimen();
}
}
Now:
fixture.Customizations.Add(new PropertyTypeExclusion<Release, IdentityRef>());
fixture.Create<Release>(); // the `IdentityRef` prop is omitted
fixture.Create<SomeOtherType>(); // the `IdentityRef` prop is NOT omitted