You can create a custom attribute for this, such as this CollectionSizeAttribute
:
[Theory, AutoData]
public void CollectionSizeTest(
List<int> defaultSize,
[CollectionSize(5)] List<int> customSize,
[CollectionSize(6)] List<int> customSize2,
[CollectionSize(0)] IEnumerable<string> empty,
List<string> defaultSize2
)
{
Assert.Equal(3, defaultSize.Count);
Assert.Equal(5, customSize.Count);
Assert.Equal(6, customSize2.Count);
Assert.Empty(empty);
Assert.Equal(3, defaultSize2.Count);
}
public class CollectionSizeAttribute : CustomizeAttribute
{
private readonly int _size;
public CollectionSizeAttribute(int size)
{
_size = size;
}
public override ICustomization GetCustomization(ParameterInfo parameter)
{
if (parameter == null) throw new ArgumentNullException(nameof(parameter));
var objectType = parameter.ParameterType.GetGenericArguments()[0];
var isTypeCompatible =
parameter.ParameterType.IsGenericType
&& parameter.ParameterType.GetGenericTypeDefinition().MakeGenericType(objectType).IsAssignableFrom(typeof(List<>).MakeGenericType(objectType))
;
if (!isTypeCompatible)
{
throw new InvalidOperationException($"{nameof(CollectionSizeAttribute)} specified for type incompatible with List: {parameter.ParameterType} {parameter.Name}");
}
var customizationType = typeof(CollectionSizeCustomization<>).MakeGenericType(objectType);
return (ICustomization) Activator.CreateInstance(customizationType, parameter, _size);
}
public class CollectionSizeCustomization<T> : ICustomization
{
private readonly ParameterInfo _parameter;
private readonly int _repeatCount;
public CollectionSizeCustomization(ParameterInfo parameter, int repeatCount)
{
_parameter = parameter;
_repeatCount = repeatCount;
}
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new FilteringSpecimenBuilder(
new FixedBuilder(fixture.CreateMany<T>(_repeatCount).ToList()),
new EqualRequestSpecification(_parameter)
));
}
}
}
This causes the parameter to be created as a list with the given size by calling fixture.CreateMany<T>(_repeatCount)
.