如何使用SpecFlow中的table.CreateSet <>(myClass)()生成缺失值?

Max*_*Max 3 c# bdd specflow

我第一次使用SpecFlow为我的项目编写测试,我遇到了一个小问题.

我有下一堂课:

public class FancyName
{
    [DataMember]
    public Guid Guid { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public List <Country> Countries { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想在我的测试中使用SpecFlow助手生成这个类.

以下是场景的一部分:

[...]
When i add some names
    | Name | Countries |
    | UK   | 1         |
    | US   | 2         |
[...]
Run Code Online (Sandbox Code Playgroud)

我尝试在步骤定义中解析它,如下所示:

[When(@"I add some names")]
public void AddNames(Table table)
{
    var names = table.CreateSet<FancyName>();
    [...]
}
Run Code Online (Sandbox Code Playgroud)

我遇到了两个问题:

  1. 我没有传递Guid,因为想要生成它就像Guid.NewGuid()创建对象一样包含null
  2. 我通过国家排序,但我需要创建List<Country>().

我曾经尝试迭代表并FancyName手动创建对象,但据我所知它不是SpecFlow方式.我试图查看文档,并没有找到合适的解决方案.

可能有人知道解决这个问题的真正好方法吗?提前致谢.

Dar*_*ren 9

这里主要的SpecFlow.Assist作者......

我同意上面的@ sam-holder Table.CreateSet<T>不是魔术,在这种情况下,转换可能是一个更简单的解决方案.但是,Assist确实具有完成所要求的功能所需的功能.:)

我想解释一下.我看到两个问题呈现为:

1)如何在每条记录上设置Guid?

2)如何将字符串值转换为数组?

对于(1),答案很简单.您可以将函数传递给CreateSet,告诉库如何实例化您要创建的对象.既然你只想设置Guid,你可以这样做:

    table.CreateSet<FancyName>(() => new FancyName { Guid = Guid.NewGuid()});
    // or simpler, table.CreateSet(() => new FancyName { Guid = Guid.NewGuid()});
Run Code Online (Sandbox Code Playgroud)

对于(2),你将不得不做更多的编程.您希望Assist知道如何将字符串转换为列表.为此,您必须创建一个"值检索器"并将其注册到Assist.我能够使用以下代码执行此操作:

public class CountryRetriever : IValueRetriever
{
    public bool CanRetrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type propertyType)
    {
        return propertyType.FullName.StartsWith("System.Collections.Generic.List`1[[SpecFlowExample.Country");
    }

    public object Retrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type propertyType)
    {
        return keyValuePair.Value.Split(',')
            .Select(x => new Country {Name = x})
            .ToList();
    }
}

[Binding]
public class Steps
{
    [BeforeTestRun]
    public static void Setup()
    {
        TechTalk.SpecFlow.Assist.Service.Instance.RegisterValueRetriever(new CountryRetriever());
    }

    [When(@"i add some names")]
    public void WhenIAddSomeNames(Table table)
    {
        var things = table.CreateSet<FancyName>(() => new FancyName { Guid = Guid.NewGuid()});

    }
}
Run Code Online (Sandbox Code Playgroud)

直接指向这样的列表,特别是使用字符串,非常hacky,但这段代码确实有效.

国家/地区检索器将宣布它可以在遇到List<Country>类型时处理字符串的转换.然后它会拆分字符串并创建一个国家/地区列表.

SpecFlow使用大多数基本.Net类型的值检索器开始每次测试运行,但不是你的List<Country>.为了适应您的类型,您需要在每次测试运行之前注册新的值检索器.