2017-01-13 8 views
3

я пытаюсь исключить определенные значения перечисления, такие как Unknown и Uninitialized из множества значений любого типа перечисления.Как исключить определенные перечисления из всех типов перечисления

я могу видеть, что Enums генерируются циклическим использование EnumGenerator из множества всех возможных Enum значений для данного типа Enum.

На основе этого кода, моя первая мысль построить ISpecimenBuilder, который проверяет Type.IsEnum и делает context.Resolve(request), пока Resolve возвращает значение, которое не входит в список исключений.

Проблема в том, что это дает мне ошибку рекурсии. После проверки исходного кода я понимаю, почему - если строитель обрабатывает запрос и снова вызывает другой номер Resolve с тем же запросом, вы попадете в бесконечный цикл.

Но поскольку EnumGenerator не является расширяемым, и я не могу понять, как перехватить цепочку сборки. Я не понимаю, как это решить.

ответ

2

Вы можете создать пользовательский Specimen Builder, который использует существующие EnumGenerator, но пропускает значения, которые вам не нужны. В этом образце я использую метод specimen.ToString() преднамеренно для того, чтобы не быть связан с каким-либо конкретной enum типа:

public class ExcludeUnknownEnumGenerator : ISpecimenBuilder 
{ 
    private readonly EnumGenerator _enumGenerator = new EnumGenerator(); 

    public object Create(object request, ISpecimenContext context) 
    { 
     var enumType = request as Type; 
     if (enumType == null || !enumType.IsEnum) 
     { 
      return new NoSpecimen(); 
     } 

     var namesEnumerator = Enum.GetNames(enumType).GetEnumerator(); 
     while (namesEnumerator.MoveNext()) 
     { 
      var specimen = _enumGenerator.Create(request, context); 
      if (specimen.ToString() != "Unknown" && 
       specimen.ToString() != "Uninitialized") 
      { 
       return specimen; 
      } 
     } 

     throw new ObjectCreationException(
      "AutoFixture was unable to create a value for " + 
      enumType.FullName + 
      " since it is an enum containing either no values or " + 
      "ignored values only ('Unknown' and 'Uninitialized'). " + 
      "Please add at least one valid value to the enum."); 
    } 
} 

public enum EnumWithUnknown 
{ 
    Known, 
    Unknown, 
    Wellknown, 
    Uninitialized 
} 

Следующий код показывает enum значения без Unknown и Uninitialized состояний:

var fixture = new Fixture(); 
fixture.Customizations.Insert(0, new ExcludeUnknownEnumGenerator()); 

Console.Out.WriteLine("result = {0}", fixture.Create<EnumWithUnknown>()); 
Console.Out.WriteLine("result = {0}", fixture.Create<EnumWithUnknown>()); 
Console.Out.WriteLine("result = {0}", fixture.Create<EnumWithUnknown>()); 
Console.Out.WriteLine("result = {0}", fixture.Create<EnumWithUnknown>()); 

*** ConsoleOutput *** 

result = Known 
result = Wellknown 
result = Known 
result = Wellknown 
+0

Не было бы проще ли украсить существующий «EnumGenerator»? –

+0

Я вызываю класс 'EnumGenerator' в методе' Create'. Когда вы говорите «проще», вы имеете в виду сокращение метода Create каким-то образом? –

+0

Примите мои извинения; Я не читал код достаточно тщательно, прежде чем написал этот комментарий. –