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

How to transform Spec-flow table data into different values

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

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

无论如何我都不知道自动执行此操作,所以我只能想到两种可能性。

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

正如 Sam 所指出的,我们可以使用 StepArgumentTransformarion 或类似于下面的方法。如果要使用 typeof(T).Name.Equals(typeof(yourtype).Name) 作为条件

将一种类型的 Value1 映射到 Code1 并将 Value1 映射到另一种类型的 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;
    }

我已经开始使用 "Test Models,",它最终成为我的规范流测试的视图模型。

使用你的例子:

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; }
}

和 "Test Model":

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
}

对于这个特定的示例,它可能超出您的需要,但我发现当场景中的数据需要采用人类可读的格式时,这种模式很有效,这种格式被转换为复杂的格式你的域模型。

我用 提出了类似的问题。似乎应该可以将 StepArgumentTransforms 应用于 CreateInstance/CreateSet,但对于已经在 table 转换中转换的基本类型,还没有实现。

在你的情况下(与我的情况不同),我认为你可以使用自定义 ValueRetriever.

相对容易地做到这一点

您可以通过

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