2016-04-25 6 views
1

私は、作成しようとしている型にその列挙型が含まれているときに、AutoFixtureに列挙型のランダムな値を使用したいと思います。基本的にはhttps://github.com/AutoFixture/AutoFixture/issues/360と同じですが、列挙型の場合です。ランダムな列挙生成

私は以下を試みましたが、AutoFixtureは要求された型の代わりに列挙型を作成しようとしましたが、キャストできません。

public class RandomEnumSequenceGenerator<T> : ISpecimenBuilder where T : struct 
{ 
    private static Random _random = new Random(); 
    private Array _values; 

    public RandomEnumSequenceGenerator() 
    { 
     if (!typeof(T).IsEnum) 
     { 
      throw new ArgumentException("T must be an enum"); 
     } 
     _values = Enum.GetValues(typeof(T)); 
    } 

    public object Create(object request, ISpecimenContext context) 
    { 
     var index = _random.Next(0, _values.Length - 1); 
     return _values.GetValue(index); 
    } 
} 

私は、この

public class BaseUnitTestClass 
    { 
     internal static Fixture _fixture = new Fixture(); 

     public BaseUnitTestClass() 
     {    
      _fixture.Customizations.Add(new RandomEnumSequenceGenerator<TableType>()); 
     } 

ように私のBaseUnitTestクラスでそれを使用する私は、ソースコードをプルダウンし、それがcomposedBuildersをループし、最後のものだけ(RandomEnumSequenceGenerator)が契約を満たしていることに気づきましたその後、TableType列挙型の値を作成し、例外をスローする作成しようとしている実際のクラスとしてキャストしようとします。

at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context, T seed) at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context) at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenBuilder builder) at UnitTests.Unit.BaseUnitTestClass.GetRandomT in mypath\BaseUnitTestClass.cs:line 49 Result Message: System.InvalidCastException : Unable to cast object of type 'MyNamespace.TableType' to type 'MyNameSpace.AssumptionChangeCriteria'.

AssumptionChangeCriteriaが列挙されるタイプTableTypeの性質を有し、以下のように

例外メッセージです。

public class RandomEnumSequenceGenerator<T> : ISpecimenBuilder where T : struct 
{ 
    private static Random _random = new Random(); 
    private T[] _values; 

    public RandomEnumSequenceGenerator() 
    { 
     if (!typeof(T).IsEnum) 
     { 
      throw new ArgumentException("T must be an enum"); 
     } 

     _values = Enum.GetValues(typeof(T)) 
      .Cast<T>() 
      .ToArray(); 
    } 

    public object Create(object request, ISpecimenContext context) 
    { 
     var index = _random.Next(_values.Length); 
     return _values[index]; 
    } 
} 
+0

例外の詳細はありますか? – Xiaoy312

+2

Random.Next()の最大値は、包括的ではないため、values.Length - 1 btwを実行する必要はありません。 –

答えて

2

RandomEnumSequenceGenerator<T>のバージョンがrequestを確認し、それはありません。

return _fixture.Create<T>(); 
+0

実行時に、enum(TableType)のリクエストが来たときに、このtは常にnullになります。タイプへのキャストは失敗します。 – reggaeguitar

+1

'fixture.Customizations.Insert(0、new RandomEnumSequenceGenerator ())'を試してください。 –

+0

それはトリックをした、ありがとう – reggaeguitar

2

これは、それが犯人であると仮定すると、型キャスト例外を修正する必要がありますが、次のようにGetRandom<T>がある

カスタム化するタイプのリクエストではなくても、のいずれかのリクエストに応答します。

最も簡単な修正は、おそらくこのようなものです:私はこれをコンパイルしてテストするために試したことがないので、あなたはそれを少し微調整する必要がありますが、それは何の要点を示すべき

public class RandomEnumSequenceGenerator<T> : ISpecimenBuilder where T : struct 
{ 
    private static Random _random = new Random(); 
    private Array _values; 

    public RandomEnumSequenceGenerator() 
    { 
     if (!typeof(T).IsEnum) 
     { 
      throw new ArgumentException("T must be an enum"); 
     } 
     _values = Enum.GetValues(typeof(T)); 
    } 

    public object Create(object request, ISpecimenContext context) 
    { 
     var t = request as Type; 
     if (t == null || t != typeof(T)) 
      return new NoSpecimen(); 

     var index = _random.Next(0, _values.Length - 1); 
     return _values.GetValue(index); 
    } 
} 

する必要があります。

+0

例外をスローしているキャストがオートフィックスのソースコードにありますが、これで問題は解決されません。試してくれてありがとう。 – reggaeguitar

+0

例外メッセージとスタックトレースを提供できますか? – Xiaoy312

関連する問題