3

这是一个 json 生成:

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

我怎样才能在我stringjson测试主体中创建它来断言最终结果。

4

2 回答 2

4

我最初的答案是使用Gen.map2组合两个生成器,一个用于字符串数组,一个用于 json 字符串。但是Gen.map2专门设计为让两个独立的生成器组合在一起,即一个生成器的结果不会影响另一个生成器的结果。(例如,掷两个骰子:第一个骰子的结果与第二个骰子的结果无关)。您需要的是一个简单的Gen.map,它采用字符串数组生成器并生成(字符串数组,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 将始终匹配字符串数组。

原始的,不正确的,下面的答案,如果两个答案之间的对比有用,请保留:

简单的。只需保存数组生成器,稍后再使用它,Gen.map2用于组合数组和 json。例如:

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

现在你有了一个生成 2 元组的生成器。元组的第一个元素是字符串数组,第二个元素是生成的 json。

顺便说一句,您的 JSON 创建代码还不是很正确,因为如果生成的字符串包含引号,您需要以某种方式引用它们,否则您生成的 JSON 将无效。但是我会让你处理这个问题,或者如果你不知道如何处理这个问题,我会提出一个新的问题。“单一责任原则”也适用于 Stack Overflow 问题:理想情况下,每个问题都应该只涉及一个主题。

于 2018-01-02T12:42:20.637 回答
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)
于 2018-01-21T11:33:30.700 回答