2013-07-16 103 views
5

如何修改Float,Double和decimal的AutoFixture创建方法,以便在创建这些类型时还会有余数?Autofixture - 创建一个float,double或decimal,余数为

目前我这样做,但这会抛出异常。

var fixture = new Fixture(); 
fixture.Customize<double>(sb => sb.FromFactory<double>(d => d * 1.33)); //This should add remainder 
var value = fixture.Create<double>(); 

回答

6

试图通过使用的值,以重新定义类型(double)相同类型(double)确实会产生无限递归。但是,通过将种子输入更改为另一种类型即可轻松完成此工作 - 例如,一个int

var fixture = new Fixture(); 
fixture.Customize<double>(c => c.FromFactory<int>(i => i * 1.33)); 
var value = fixture.Create<double>(); 

双打现在往往也有分数值。

+0

我想我没有真正想过在后台如何工作,并且定制创建了无限递归。感谢澄清这一点! – Rok

+0

+1这非常整齐! :) –

5

一种选择是使用自定义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); 
     } 
    } 
} 
+0

Nikos感谢您的帮助,但Mark的回答更符合我所搜索的内容。 – Rok

+1

+1使这个SpecimenBuilder线程安全的任何原因 - 您是否对所有的构建者都这样做? (我明白为什么一个随机需要被守护,从来没有想过在SpecimenBuilder中添加这个守护,我永远不会从Fixture和/或Generator发出来保证线程安全,我当然可以理解,esp给予@ ploeh在V3.0中的不变性工作,它可能相对容易实现)。或者我错过了一篇博文:P –

+0

+1这也可以在没有线程安全的情况下工作。几乎所有的数字序列生成器都是线程安全的,但其中大部分(如果不是全部)都是在3.0之前创建的。 –