2016-04-25 8 views
1

Ich möchte, dass AutoFixture einen zufälligen Wert einer Aufzählung verwendet, wenn diese Aufzählung in einem Typ enthalten ist, den ich erstellen möchte. Grundsätzlich das gleiche wie dieses https://github.com/AutoFixture/AutoFixture/issues/360 aber für enums.Zufallsgenerierung

Ich habe Folgendes versucht, aber AutoFixture versucht, die enum anstelle des angeforderten Typs zu erstellen und kann es nicht umwandeln.

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); 
    } 
} 

ich dann verwenden, in meiner BaseUnitTest Klasse wie diese

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

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

ich den Quellcode nach unten gezogen und festgestellt, dass es den composedBuilders und nur der letzten Schleife durch (der RandomEnumSequenceGenerator) erfüllt den Vertrag Es erstellt dann einen TableType-Enumerationswert und versucht, es als die tatsächliche Klasse, die ich erstellen möchte, zu werfen, die eine Ausnahme auslöst.

Die Ausnahmemeldung ist wie folgt:

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 eine Eigenschaft vom Typ hat, die eine ENUM TableType ist.

wo GetRandom<T> ist wie folgt

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

Können wir das Detail der Ausnahme haben? – Xiaoy312

+2

Sie müssen keine Werte machen. Länge - 1 Btw, weil der Maximalwert für Random.Next() nicht inklusive ist. –

Antwort

2

Ihre Version von RandomEnumSequenceGenerator<T> nicht die request überprüfen, so dass es reagiert nur auf any Anfrage, auch wenn es keine Anfrage für den Typ ist, den es anpasst.

Die einfachste Lösung ist wahrscheinlich so etwas wie folgt aus:

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); 
    } 
} 

ich nicht, dies zu kompilieren und zu testen versucht haben, so können Sie es ein bisschen kann zwicken, aber es sollte den Kern dessen, was Sie demonstrieren werde ich tun müssen.

+0

Wenn ich dies t immer Null ist, wenn die Anfrage für die enum (TableType) hereinkommt, z. Die Umwandlung in Typ schlägt fehl. – reggaeguitar

+1

Probieren Sie 'fixture.Customizations.Insert (0, new RandomEnumSequenceGenerator ())'. –

+0

Das hat den Trick gemacht, vielen Dank für Ihre Hilfe – reggaeguitar

2

Dies sollte die Typumwandlung Ausnahme behebt, dass unter der Annahme, ist der Täter:

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

Der Cast, der die Ausnahme auslöst, befindet sich im AutoFixture-Quellcode. Dadurch wird das Problem nicht behoben. Danke fürs ausprobieren. – reggaeguitar

+0

Können Sie die Ausnahmebedingungsnachricht und Stacktrace bereitstellen? – Xiaoy312