我正在使用specflow和selenium,我正在制作一个表来构建网站中的用户输入。
| Input1 | Input2 | Input3 |
| Opt1 | OptX | Opt2 |
我为输入构建了一个类:
public class ObjectDTO
{
public string Input1;
public Input2Type Input2;
public string Input3;
}
一个特定opt的枚举(因为它是一个静态输入)
public enum Input2Type
{
[StringValue("OptX")]
X,
[StringValue("OptY")]
Y,
[StringValue("OptZ")]
Z
}
当我得到输入时,我尝试实例化对象:
ObjectDTO stocks = table.CreateInstance<ObjectDTO>();
但是它说“没有值得发现的有价值的枚举”。
答案 0 :(得分:1)
不幸的是table.CreateInstance()是一个相当天真的方法,并且对于Enums(除其他外)失败。我最后编写了一个表的扩展方法,该方法使用反射来询问它试图创建的对象实例。这种方法的好处是该方法只会覆盖表列中指定的实例值,但是,您必须为表的每一行调用它并传入已经实例化的实例。它可以很容易地修改为像CreateInstance方法一样,但为了我的目的,这工作得更好......
public static class TableExtensions
{
public static void FillInstance(this Table table, TableRow tableRow, object instance) {
var propertyInfos = instance.GetType().GetProperties();
table.Header.Each(header => Assert.IsTrue(propertyInfos.Any(pi => pi.Name == header), "Expected to find the property [{0}] on the object of type [{1}]".FormatWith(header, instance.GetType().Name)));
var headerProperties = table.Header.Select(header => propertyInfos.Single(p => p.Name == header)).ToList();
foreach (var propertyInfo in headerProperties) {
object propertyValue = tableRow[propertyInfo.Name];
var propertyType = propertyInfo.PropertyType;
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
propertyType = propertyType.GetGenericArguments().Single();
}
var parse = propertyType.GetMethod("Parse", new[] { typeof(string) });
if (parse != null) {
// ReSharper disable RedundantExplicitArrayCreation
try {
propertyValue = propertyType.Name.Equals("DateTime") ? GeneralTransformations.TranslateDateTimeFrom(propertyValue.ToString()) : parse.Invoke(null, new object[] { propertyValue });
} catch (Exception ex) {
var message = "{0}\r\nCould not parse value: {2}.{3}(\"{1}\")".FormatWith(ex.Message, propertyValue, parse.ReturnType.FullName, parse.Name);
throw new Exception(message, ex);
}
// ReSharper restore RedundantExplicitArrayCreation
}
propertyInfo.SetValue(instance, propertyValue, null);
}
}
}
您可以按如下方式调用它:
ObjectDTO objectDTO;
foreach (var tableRow in table.Rows)
{
objectDTO = table.FillInstance(tableRow, new ObjectDTO());
//Do individual row processing/testing here...
}