在FsCheck中生成唯一字符串

时间:2016-01-15 06:12:10

标签: c# fscheck property-based-testing

我需要生成唯一的非null字符串,以用作Dictionary个键。我试过像:

 public static Gen<NonNull<string>> UniqueStrings()
 {
     return from s in Arb.Default.NonNull<string>().Generator
            select s;
 }

然后我在{/ p>中使用UniqueString()

public static Arb<Foo> Foos()
{
    // Foo's constructor will use the string parameter
    // as key to an internal Dictionary
    return (from nonNullString in UniqueStrings()
            select new Foo(nonNullString.Item)).ToArbitrary();
}

但是,我在属性测试Foo中遇到异常,因为FsCheck有时会生成两次相同的字符串,从而产生DuplicateKeyException

如何生成要传递给Foo的构造函数的唯一字符串?

3 个答案:

答案 0 :(得分:3)

您不能强制FsCheck生成器生成唯一值,因为您基本上无法访问以前生成的值的历史记录,FsCheck本身也不会保证唯一性。

在这种情况下你可以做的就是生成说出一个字符串列表,然后使用Distinct()作为列表的唯一性。然后,您还可以使用类似的方法生成Foo列表。

例如:

Gen<Foo[]> res = from s in Arb.Default.Set<string>().Generator
                 select s.Select(ss => new Foo(ss)).ToArray();

(注意你不能使用from来获取ss因为C#不允许你混合使用不同的LINQ方法,一个在Gen上,一个在IEnumerable上)

一个提议,我想知道这不是你要检查的额外属性。如果Foo的用户应该给它一个唯一的字符串,那怎么支持?如果他们不这样做会怎么样?

答案 1 :(得分:2)

要生成唯一字符串,您可以使用Guid生成器,它是生成唯一字符串的标准方法,即使在多台计算机上也是如此。

答案 2 :(得分:0)

您可以在插入字典之前添加简单的检查,而不是生成uniq字符串。

更新: 好。一代又一代地改变你的字符串。你可以阅读here
它与Integer数组有关,但您可以轻松地为字符串

自定义它