2015-05-20 17 views
4

我已經表明一類,它有兩個參數:如何在Autofixture中使用RandomRangedNumberCustomization來確保參數在一定範圍內?

public double X { get; private set; } 

    public double Y { get; private set; } 

    public Point(double x, double y) 
    { 
     if (x > 90 || x < -90) 
      throw new ArgumentOutOfRangeException("latitude"); 

     if (y > 180 || y < -180) 
      throw new ArgumentOutOfRangeException("longitude"); 

     X = x; 
     Y = y; 
    } 

相應的屬性在構造函數中設置,所以我需要告訴AutoFixture創建與範圍內的參數點類作爲中後衛的規定條款。我設法弄亂了RandomRangedNumberCustomization類的用法。我做了以下內容:

 var xRange = new RangedNumberRequest(typeof(double), -90.0, 90.0); 
     var yRange = new RangedNumberRequest(typeof (double), -180.0, 180.0); 
     var dummyContext = new DelegatingSpecimenContext(); 
     var generator = new RandomRangedNumberGenerator(); 
     var x = (double)generator.Create(latitudeRange, dummyContext); 
     var y = (double) generator.Create(longitudeRange, dummyContext); 

將在我的範圍內產生的數字,所以我可以創造一個點,並在這些生成的數字飼料,但我錯過在定製方面的東西。任何幫助和/或指導將不勝感激。

謝謝!

回答

4
由尼科斯Baxevanis建議的解決方案

除此之外,這裏的另一種選擇。你可以實現一個約定,一直負責處理Point在一個特定的方式xy參數:

public class PointCustomization : ICustomization 
{ 
    public void Customize(IFixture fixture) 
    { 
     fixture.Customizations.Add(new XBuilder()); 
     fixture.Customizations.Add(new YBuilder()); 
    } 

    private class XBuilder : ISpecimenBuilder 
    { 
     public object Create(object request, ISpecimenContext context) 
     { 
      var pi = request as ParameterInfo; 
      if (pi == null || 
       pi.Name != "x" || 
       pi.Member.DeclaringType != typeof(Point)) 
       return new NoSpecimen(request); 

      return context.Resolve(
       new RangedNumberRequest(typeof(double), -90d, 90d)); 
     } 
    } 

    private class YBuilder : ISpecimenBuilder 
    { 
     public object Create(object request, ISpecimenContext context) 
     { 
      var pi = request as ParameterInfo; 
      if (pi == null || 
       pi.Name != "y" || 
       pi.Member.DeclaringType != typeof(Point)) 
       return new NoSpecimen(request); 

      return context.Resolve(
       new RangedNumberRequest(typeof(double), -180d, 180d)); 
     } 
    } 
} 

(有空間在上面的代碼重構)

鑑於PointCustomization,這個測試通過:

[Fact] 
public void CreatePointDoesNotThrow() 
{ 
    var fixture = new Fixture().Customize(new PointCustomization()); 
    var e = Record.Exception(() => fixture.Create<Point>()); 
    Assert.Null(e); 
} 
+1

謝謝,馬克。我喜歡使用慣例,並在過去使用它們。我正在查看RangedNumber類,並不確定使用它們的最佳方式,所以這有所幫助。我仍然不確定如何使用RandomRangedNumberCustomization,如果它在我的特定情況下具有應用程序。 – TortillaCurtain

4

應該有幾種自定義AutoFixture的方法。 - 這裏是他們幾個:

隨着數據註釋

public class Point 
{ 
    public double X { get; private set; } 
    public double Y { get; private set; } 

    public Point(
     [Range(-90, 90)]double x, 
     [Range(-180, 180)]double y) 
    { 
     if (x > 90 || x < -90) 
      throw new ArgumentOutOfRangeException("latitude"); 

     if (y > 180 || y < -180) 
      throw new ArgumentOutOfRangeException("longitude"); 

     this.X = x; 
     this.Y = y; 
    } 
} 

[Fact] 
public void CreatePointDoesNotThrow() 
{ 
    var fixture = new Fixture(); 
    Assert.DoesNotThrow(() => fixture.Create<Point>()); // Passes. 
} 

搭配發電機

public class Point 
{ 
    public double X { get; private set; } 
    public double Y { get; private set; } 

    public Point(double x, double y) 
    { 
     if (x > 90 || x < -90) 
      throw new ArgumentOutOfRangeException("latitude"); 

     if (y > 180 || y < -180) 
      throw new ArgumentOutOfRangeException("longitude"); 

     this.X = x; 
     this.Y = y; 
    } 
} 

[Fact] 
public void CreatePointDoesNotThrow() 
{ 
    var fixture = new Fixture(); 
    var x = new Generator<int>(fixture).First(pt => pt > -90 && pt < 90); 
    var y = new Generator<int>(fixture).First(pt => pt > -180 && pt < 180); 
    fixture.Customize<Point>(c => c 
     .FromFactory(() => new Point(x, y))); 

    Assert.DoesNotThrow(() => fixture.Create<Point>()); // Passes. 
} 
+1

感謝您的回答。我不是數據註釋的忠實粉絲,但他們很方便。我喜歡你關於使用Generator的想法,這對我來說是新的,所以我也非常感謝。最終,我喜歡約定,所以我接受了馬克的答案,但是你的想法也是一個很好的想法,並且當我不需要整個約定時,我打算將它用於一次性測試。 – TortillaCurtain

相關問題