如何将Spec-flow表数据转换为不同的值

时间:2015-07-31 05:27:13

标签: c# cucumber bdd specflow

我需要转换通过table.CreateInstance()table.CreateSet()获得的Spec-flow表数据。我正在使用Spec流进行DB测试,在某些情况下,Table字段值需要映射到不同的值,因为DB表存储代码而不是我们在功能文件表中输入的值。我不想在功能文件中包含代码,因为它会降低可读性。例如,如果我输入了单个状态,如下所述,我希望它在数据传输对象/ POCO中映射或转换为 S 。什么是最好的方法?提前谢谢。

Given I entered the following data into the new account form:
| Name        | Birthdate | Status      |
| John Butcher| 2/2/1902  | Single      |

5 个答案:

答案 0 :(得分:3)

我开始使用“测试模型”,最终成为我的规格流测试的视图模型。

使用您的示例:

Given I entered the following data into the new account form:
    | Name        | Birthdate | Status      |
    | John Butcher| 2/2/1902  | Single      |

域名模型:

public class Account
{
    public string Name { get; set; }
    public DateTime? Birthdate { get; set; }
    public string Status { get; set; }
}

和“测试模型”:

public class AccountForm
{
    public string Name { get; set; }
    public DateTime? Birthdate { get; set; }
    public string Status { get; set; }

    public Account CreateInstance()
    {
        return new Account()
        {
            Name = Name,
            Birthdate = Birthdate,
            Status = Status.Substring(0, 1)
        };
    }
}

步骤定义:

[Given(@"Given I entered the following data into the new account form:")]
public void GivenIEnteredTheFollowingDataIntoTheNewAccountForm(Table table)
{
    var form = table.CreateInstance<AccountForm>();
    var account = form.CreateInstance();

    // save to the database
}

对于这个特定的例子,它可能比你需要的更多,但我发现当场景中的数据需要采用人类可读的格式时,这种模式很有效,这种格式在你的域中被翻译成复杂的格式模型。

答案 1 :(得分:2)

我自动不知道这样做,所以我只能想到两种可能性。

  1. 请勿使用CreateInstanceCreateSet方法,而是手动执行所有映射,但将其封装在[StepArgumentTransformation]
  2. 使用您正在使用的方法,然后覆盖自动生成的&#39; Single&#39; &#39; S&#39;在创建实例后。

答案 2 :(得分:0)

Sam指出,我们可以使用StepArgumentTransformarion或类似于下面的方法。如果要将Value1映射到一种类型的Code1,将Value1映射到使用typeof(T).Name.Equals(typeof(yourtype).Name)作为条件的另一种类型的CodeX,则在扩展方法中添加if else

 public static IEnumerable<T> CreateSetWithValueTransfer<T>(this Table table)
    {
        var mapper = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
        {
            {"Value1", "Code1"},
            {"value2", "Code2"}
        };

        var set = ChangeValues(table, mapper);
        return set.CreateSet<T>();
    }


    private static Table ChangeValues(Table table, Dictionary<string, string> mapper)
    {
        var mappedTable = new Table(table.Header.ToArray());
        foreach (var row in table.Rows)
        {
            mappedTable.AddRow(row.Values.Select(x => mapper.ContainsKey(x) ? mapper[x] : x).ToArray());
        }
        return mappedTable;
    }

答案 3 :(得分:0)

我用different example here提出了类似的问题。看起来应该可以将StepArgumentTransforms应用于CreateInstance / CreateSet,但尚未针对已经在表转换中转换的基本类型实现。

在您的情况下(与我的不同),我认为您可以使用自定义ValueRetriever相对轻松地完成此操作。

答案 4 :(得分:0)

您可以通过

从表中获取值
table.Rows.FirstOrDefault().Values.FirstOrDefault();