作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试基于此示例中的 CompositeDataAttribute
创建 AutoPropertyDataAttribute
AutoFixture: PropertyData and heterogeneous parameters .
它对单组参数有效,但对更多参数组无效。这是代码:
public static IEnumerable<object[]> NumericSequence
{
get
{
yield return new object[] {1};
//yield return new object[] {2};
}
}
[Theory]
[AutoPropertyData("NumericSequence")]
public void Test(int? p1, int? p2, int? p3)
{
Assert.NotNull(p1);
Assert.NotNull(p2);
}
public class AutoPropertyDataAttribute : CompositeDataAttribute
{
public AutoPropertyDataAttribute(string propertyName)
: base(
new DataAttribute[] {
new PropertyDataAttribute(propertyName),
new AutoDataAttribute()
})
{
}
}
尝试取消注释第二个 yield
将中断测试并显示消息:
System.InvalidOperationException: Expected 2 parameters, got 1 parameters
at Ploeh.AutoFixture.Xunit.CompositeDataAttribute.<GetData>d__0.MoveNext()
at Xunit.Extensions.TheoryAttribute.<GetData>d__7.MoveNext()
at Xunit.Extensions.TheoryAttribute.EnumerateTestCommands(IMethodInfo method)
ClassDataAttribute
也是如此
最佳答案
我遇到了这个问题并决定实现一个自定义的 DataAttribute 来解决这个问题。我不能使用任何一个属性作为基类(原因如下)所以我只是从每个属性的源中获取我需要的东西。谢谢OSS :)
注意事项:
PropertyDataAttribute
用作基类AutoDataAttribute
用作基类或下面的内联源代码:
public class AutoPropertyDataAttribute : DataAttribute
{
private readonly string _propertyName;
private readonly Func<IFixture> _createFixture;
public AutoPropertyDataAttribute(string propertyName)
: this(propertyName, () => new Fixture())
{ }
protected AutoPropertyDataAttribute(string propertyName, Func<IFixture> createFixture)
{
_propertyName = propertyName;
_createFixture = createFixture;
}
public Type PropertyHost { get; set; }
private IEnumerable<object[]> GetAllParameterObjects(MethodInfo methodUnderTest)
{
var type = PropertyHost ?? methodUnderTest.DeclaringType;
var property = type.GetProperty(_propertyName, BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
if (property == null)
throw new ArgumentException(string.Format("Could not find public static property {0} on {1}", _propertyName, type.FullName));
var obj = property.GetValue(null, null);
if (obj == null)
return null;
var enumerable = obj as IEnumerable<object[]>;
if (enumerable != null)
return enumerable;
var singleEnumerable = obj as IEnumerable<object>;
if (singleEnumerable != null)
return singleEnumerable.Select(x => new[] {x});
throw new ArgumentException(string.Format("Property {0} on {1} did not return IEnumerable<object[]>", _propertyName, type.FullName));
}
private object[] GetObjects(object[] parameterized, ParameterInfo[] parameters, IFixture fixture)
{
var result = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
if (i < parameterized.Length)
result[i] = parameterized[i];
else
result[i] = CustomizeAndCreate(fixture, parameters[i]);
}
return result;
}
private object CustomizeAndCreate(IFixture fixture, ParameterInfo p)
{
var customizations = p.GetCustomAttributes(typeof (CustomizeAttribute), false)
.OfType<CustomizeAttribute>()
.Select(attr => attr.GetCustomization(p));
foreach (var c in customizations)
{
fixture.Customize(c);
}
var context = new SpecimenContext(fixture);
return context.Resolve(p);
}
public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, Type[] parameterTypes)
{
foreach (var values in GetAllParameterObjects(methodUnderTest))
{
yield return GetObjects(values, methodUnderTest.GetParameters(), _createFixture());
}
}
}
关于c# - AutoFixture CompositeDataAttribute 不适用于 PropertyDataAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18852608/
我正在尝试基于此示例中的 CompositeDataAttribute 创建 AutoPropertyDataAttribute AutoFixture: PropertyData and heter
我是一名优秀的程序员,十分优秀!