如何使用FsCheck生成元组

3
这是一个JSON生成示例:
let strGen = Arb.Default.String()
                |> Arb.toGen
strGen
    |> Gen.arrayOf
    |> Gen.map (String.concat "\", \"")
    |> Gen.map (fun strs -> "[\"" + strs + "\"]")

我怎样才能在测试主体中获取从json创建的字符串以断言最终结果。


当你说“已创建json的字符串”时,你指的是哪个字符串?你是指由strGen |> Gen.arrayOf生成的字符串数组吗? - rmunn
@rmunn:是的。我的意思是由strGen |> Gen.arrayOf生成的字符串数组。 - Mohsen
2个回答

4

我的原始答案是使用Gen.map2来组合两个生成器,一个用于字符串数组,另一个用于json字符串。但是Gen.map2专门设计用于让两个独立的生成器组合的,也就是说,一个生成器的结果不会影响另一个生成器的结果。(例如,掷两个骰子:第一个骰子的结果与第二个骰子的结果无关)。你需要的是一个简单的Gen.map,它接收字符串数组生成器并产生一个(string array, json)的元组。像这样:

let strGen = Arb.Default.String() |> Arb.toGen
let arrayGen = strGen |> Gen.arrayOf
arrayGen |> Gen.map (fun array ->
    let json =
        array
        |> String.concat "\", \""
        |> fun strs -> "[\"" + strs + "\"]")
    array,json)

与下面的答案不同,这里只有一个生成器,其值用于产生数组和json值。因此,这些值将是相关的而不是独立的,json将始终与字符串数组匹配。

下面是原始、不正确的答案,为了对比两个答案的有用性而保留:

Easy. Just save the array generator, and re-use it later, using Gen.map2 to combine the array and the json. E.g.:

let strGen = Arb.Default.String()
                |> Arb.toGen
let arrayGen = strGen |> Gen.arrayOf
let jsonGen =
    arrayGen
    |> Gen.map (String.concat "\", \"")
    |> Gen.map (fun strs -> "[\"" + strs + "\"]")
Gen.map2 (fun array json -> array,json) arrayGen jsonGen

And now you have a generator that produces a 2-tuple. The first element of the tuple is the string array, and the second element is the json that was generated.

BTW, your JSON-creating code isn't quite correct yet, because if the generated string contains quotation marks, you'll need to quote them in some way or your generated JSON will be invalid. But I'll let you handle that, or ask a new question about that if you don't know how to handle that. The "single responsibility principle" applies to Stack Overflow questions, too: each question should ideally be about just one subject.


2

似乎无法将代码放入评论中,因此这里是清理过的版本:

let isDigitOrWord i =
        i |> String.isNullOrEmpty 
        |> not && Regex.IsMatch(i,"^[a-zA-Z0-9 ]*$")

let strGen = Arb.Default.String() |> Arb.toGen

Gen.arrayOf strGen 
|> Gen.map (fun array ->
    let array = array |>  Array.filter isDigitOrWord
    let json =
        array
        |> String.concat "\", \"" 
        |> fun strs -> if strs|> String.isEmpty then strs else "\"" + strs + "\""
        |> fun strs -> "[" + strs + "]"
    array,json)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接