How do I modify AutoFixture create method for float, double and decimal, so that when these types get created they will also have a remainder?
Currently I do this, but this throws exception.
var fixture = new Fixture();
fixture.Customize<double>(sb => sb.FromFactory<double>(d => d * 1.33)); //This should add remainder
var value = fixture.Create<double>();
Attempting to redefine a type (double
) by using a value of the same type (double
) will, indeed, yield an infinite recursion. However, you can easily make this work by changing the seed input into another type - e.g. an int
:
var fixture = new Fixture();
fixture.Customize<double>(c => c.FromFactory<int>(i => i * 1.33));
var value = fixture.Create<double>();
Doubles will now tend to have fractional values too.
One option is to use a custom ISpecimenBuilder
:
var fixture = new Fixture();
fixture.Customizations.Add(
new RandomDoublePrecisionFloatingPointSequenceGenerator());
The RandomDoublePrecisionFloatingPointSequenceGenerator
could look like below:
internal class RandomDoublePrecisionFloatingPointSequenceGenerator
: ISpecimenBuilder
{
private readonly object syncRoot;
private readonly Random random;
internal RandomDoublePrecisionFloatingPointSequenceGenerator()
{
this.syncRoot = new object();
this.random = new Random();
}
public object Create(object request, ISpecimenContext context)
{
var type = request as Type;
if (type == null)
return new NoSpecimen(request);
return this.CreateRandom(type);
}
private double GetNextRandom()
{
lock (this.syncRoot)
{
return this.random.NextDouble();
}
}
private object CreateRandom(Type request)
{
switch (Type.GetTypeCode(request))
{
case TypeCode.Decimal:
return (decimal)
this.GetNextRandom();
case TypeCode.Double:
return (double)
this.GetNextRandom();
case TypeCode.Single:
return (float)
this.GetNextRandom();
default:
return new NoSpecimen(request);
}
}
}
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