问题
I need generate unique non-null
strings to be used as Dictionary
keys. I tried something like:
public static Gen<NonNull<string>> UniqueStrings()
{
return from s in Arb.Default.NonNull<string>().Generator
select s;
}
Then I use UniqueString()
in:
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();
}
However, I get an exception in properties testing Foo
because FsCheck sometimes generates the same string twice, resulting in a DuplicateKeyException
.
How can I generate unique strings to be passed into the constructor of Foo
?
回答1:
You can not force an FsCheck generator to generate unique values, because you essentially have no access to the history of previously generated values, nor will FsCheck itself guarantee uniqueness.
What you can do in this case is say generate say a list of strings, and then unique-ify the list using Distinct()
for example. You can then also generate a list of Foo's using a similar approach.
For example:
Gen<Foo[]> res = from s in Arb.Default.Set<string>().Generator
select s.Select(ss => new Foo(ss)).ToArray();
(Note you can't use from to get the ss
out because C# doesn't allow you to mix different LINQ methods, one is on Gen
, one is on IEnumerable
)
A propos, I'm wondering if this is not an extra property you want to check. If the user of Foo
is supposed to give it a unique string, how is that supported? What happens if they don't?
回答2:
To generate unique strings you can use a Guid generator, it's the standard way to generate unique strings, even across multiple computers.
回答3:
Instead of generating uniq strings you can add a simple check before insert in to the dictionary.
Update:
Ok. Do shuffling your string after generation. You can read here
it is about Integer array but you can easily customize it for the string
来源:https://stackoverflow.com/questions/34805291/generating-unique-strings-in-fscheck