如何从所有枚举类型中排除某些枚举
How to exclude certain enumerations from all enumeration types
我试图从 任何枚举类型 .[=23= 的值集中排除某些枚举值,例如 Unknown
和 Uninitialized
]
我可以看到 Enums
是使用给定 Enum
类型的所有可能 Enum
值集合中的 EnumGenerator
以循环方式生成的。
基于该代码,我的第一个想法是构建一个 ISpecimenBuilder
检查 Type.IsEnum
并执行 context.Resolve(request)
直到 Resolve
returns不在排除列表中的值。
问题是这给了我一个递归错误。在检查了源代码后,我明白了为什么——如果一个构建器处理了一个请求并用相同的请求再次调用另一个 Resolve
,你将陷入无限循环。
但是由于 EnumGenerator
不可扩展,我不知道如何拦截构建链,我对如何解决这个问题感到困惑。
您可以创建自定义 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
我试图从 任何枚举类型 .[=23= 的值集中排除某些枚举值,例如 Unknown
和 Uninitialized
]
我可以看到 Enums
是使用给定 Enum
类型的所有可能 Enum
值集合中的 EnumGenerator
以循环方式生成的。
基于该代码,我的第一个想法是构建一个 ISpecimenBuilder
检查 Type.IsEnum
并执行 context.Resolve(request)
直到 Resolve
returns不在排除列表中的值。
问题是这给了我一个递归错误。在检查了源代码后,我明白了为什么——如果一个构建器处理了一个请求并用相同的请求再次调用另一个 Resolve
,你将陷入无限循环。
但是由于 EnumGenerator
不可扩展,我不知道如何拦截构建链,我对如何解决这个问题感到困惑。
您可以创建自定义 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