How can I tell AutoFixture to specify a range (min and max) on some properties when doing
MyDataClass obj = fixture.Create<MyDataClass>();
where MyDataClass has property Diameter and I only want min:1 and max:60 on this property?
You could simply add a specific ICustomization<MyDataClass>
when instantiating the fixture:
IFixture fixture = new Fixture();
fixture.Customize<MyDataClass>(c => c
.With(x => x.Diameter, () => new Random().Next(1, 61)); // maxValue is excluded, thus 61
Now, whenever you use fixture.Create<MyDataClass>()
, a new random value between 1 and 60 is set on the created instance.
Data Annotations
The easiest approach is probably adorning the property itself with a Data Annotation, although I'm not myself a huge fan of this:
public class MyDataClass
{
[Range(1, 60)]
public decimal Diameter { get; set; }
}
AutoFixture will respect the [Range]
attribute's values.
Convention-based
A better approach is, in my opinion, a convention-based approach that doesn't rely on non-enforceable attributes:
public class DiameterBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var pi = request as PropertyInfo;
if (pi == null ||
pi.Name != "Diameter" ||
pi.PropertyType != typeof(decimal))
return new NoSpecimen(request);
return context.Resolve(
new RangedNumberRequest(typeof(decimal), 1.0m, 60.0m));
}
}
This passing test demonstrates how to use it:
[Fact]
public void ResolveRangeLimitedType()
{
var fixture = new Fixture();
fixture.Customizations.Add(new DiameterBuilder());
var actual = fixture.Create<Generator<MyDataClass>>().Take(100);
Assert.True(actual.All(x => 1 <= x.Diameter && x.Diameter <= 60));
}
For more details, please refer to this other, very closely related SO Q&A.
Overcoming Primitive Obsession
Perhaps an even better approach is to listen to your tests, combat Primitive Obsession, and introduce a custom type - in this case, a Diameter
Value Object.
This is often my preferred approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With