如何修改 AutoFixture 创建浮点型、双精度型和小数型的方法,以便在创建这些类型时它们也将具有余数?
目前我这样做,但这会引发异常。
var fixture = new Fixture();
fixture.Customize<double>(sb => sb.FromFactory<double>(d => d * 1.33)); //This should add remainder
var value = fixture.Create<double>();
尝试使用相同类型的值 (
double
) 重新定义类型 (double
) 实际上会产生无限递归。但是,您可以通过将种子输入更改为另一种类型(例如一个int
:
var fixture = new Fixture();
fixture.Customize<double>(c => c.FromFactory<int>(i => i * 1.33));
var value = fixture.Create<double>();
双精度现在也往往有小数值。
一种选择是使用自定义
ISpecimenBuilder
:
var fixture = new Fixture();
fixture.Customizations.Add(
new RandomDoublePrecisionFloatingPointSequenceGenerator());
RandomDoublePrecisionFloatingPointSequenceGenerator
可能如下所示:
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);
}
}
}
似乎没有办法拦截/修改创建的值,但我认为我更喜欢的解决方案是使用第二个
Fixture
。
public static IFixture FixDecimals(
this IFixture me
) {
var f = new Fixture();
var r = new Random();
me.Register<float>(() => f.Create<float>() + r.NextSingle());
me.Register<double>(() => f.Create<double>() + r.NextDouble());
me.Register<decimal>(() => f.Create<decimal>() + (decimal)r.NextDouble());
return me;
}