如何用FsCheck生成元组?JSON生成测试中如何获取原始字符串用于断言
嘿,我来帮你搞定这两个FsCheck相关的问题!咱们一个一个来聊:
1. 如何用FsCheck生成元组?
FsCheck本身就提供了内置的元组生成器,你可以直接通过Arb.Default来获取不同类型的元组生成器,也可以自己组合生成器来定制元组内容:
使用内置元组生成器
对于常见的元组类型(比如Tuple2到Tuple8),FsCheck都有默认的Arbitrary实例。比如要生成int * string类型的元组,可以这么写:open FsCheck // 获取(int * string)类型的默认生成器 let tupleGen = Arb.Default.Tuple2<int, string>() |> Arb.toGen // 测试生成几个样本 Gen.sample 10 5 tupleGen |> printfn "%A"这段代码会生成5个
int * string的元组样本,你可以根据需要替换类型参数(比如Tuple3<float, bool, char>来生成三元组)。自定义元组生成器
如果需要更定制化的元组(比如指定元素的生成规则),可以用Gen.zip把两个独立的生成器组合起来:// 自定义int生成器(比如只生成0-100的整数) let intGen = Gen.choose(0, 100) // 自定义string生成器(比如只生成小写字母组成的字符串) let strGen = Gen.stringOfLength 5 Gen.lowercaseChar // 组合成(int * string)元组生成器 let customTupleGen = Gen.zip intGen strGen // 生成样本测试 Gen.sample 10 5 customTupleGen |> printfn "%A"这种方式能让你完全控制元组中每个元素的生成逻辑,非常灵活。
2. 如何获取JSON生成的原始字符串用于断言?
你现在的代码直接把字符串数组转换成了JSON字符串,丢失了原始的数组数据——这就导致你没法在测试里验证转换是否正确。解决思路很简单:让生成器同时返回原始字符串数组和生成的JSON字符串,这样测试时就能拿到两者做对比了。
修改你的生成器代码如下:
open FsCheck let strArrayAndJsonGen = Arb.Default.String() |> Arb.toGen |> Gen.arrayOf // 这里改成返回(原始数组, 生成的JSON)的元组 |> Gen.map (fun strs -> let json = "[\"" + String.concat "\", \"" strs + "\"]" (strs, json))
然后在测试体里,你可以直接解构这个元组,用原始数组来断言JSON的正确性:
// 示例测试:验证生成的JSON解析后和原始数组一致 Check.Quick (fun (originalStrs, jsonStr) -> // 这里可以用JSON库解析jsonStr,然后和originalStrs对比 // 比如用Newtonsoft.Json的话: let parsedArray = Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(jsonStr) parsedArray = originalStrs )
如果不想引入JSON库,也可以直接构造预期的JSON字符串来对比:
Check.Quick (fun (originalStrs, jsonStr) -> let expectedJson = "[\"" + String.concat "\", \"" originalStrs + "\"]" jsonStr = expectedJson )
这样一来,你就能在测试中同时拿到原始输入和转换后的输出,轻松验证你的JSON生成逻辑是否正确啦!
内容的提问来源于stack exchange,提问作者Mohsen
相关产品推荐
相关产品推荐

