首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >生成字符串时,Expecto FsCheck出现堆栈溢出异常

生成字符串时,Expecto FsCheck出现堆栈溢出异常
EN

Stack Overflow用户
提问于 2017-06-28 18:05:03
回答 2查看 261关注 0票数 5

我正在努力学习如何正确使用FsCheck,目前正在将其与Expecto集成。如果我使用默认的FsCheck配置,我可以运行属性测试,但是当我尝试使用我自己的生成器时,它会导致堆栈溢出异常。

这是我的发电机

代码语言:javascript
运行
复制
type NameGen() =
    static member Name() =
        Arb.generate<string * string>
        |> Gen.where (fun (firstName, lastName) ->
            firstName.Length > 0 && lastName.Length > 0
        )
        |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
        |> Arb.fromGen
        |> Arb.convert string id

我试着这样使用它:

代码语言:javascript
运行
复制
let config = { FsCheckConfig.defaultConfig with arbitrary = [typeof<NameGen>] }

let propertyTests input =
    let output = toInitials input
    output.EndsWith(".")

testPropertyWithConfig config "Must end with period" propertyTests

异常甚至在进入Gen.where函数之前就被抛出了

我做错了什么?谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-28 18:56:43

您正在尝试使用FsCheck的字符串生成器来重新定义其字符串生成器的工作方式,但是当您这样做时,它将递归地调用自身,直到耗尽堆栈空间。这是一个已知的问题:https://github.com/fscheck/FsCheck/issues/109

这个替代方案有效吗?

代码语言:javascript
运行
复制
type NameGen =
    static member Name () =
        Arb.Default.NonEmptyString().Generator
        |> Gen.map (fun (NonEmptyString s) -> s)
        |> Gen.two
        |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
        |> Arb.fromGen
票数 6
EN

Stack Overflow用户

发布于 2017-06-28 18:59:32

您正在为类型字符串定义一个新的生成器,但在其中使用的是string * string生成器,它使用的是string生成器。不幸的是,FsCheck似乎以全局可变状态存储生成器(可能有很好的理由?)我认为这意味着生成器会一直调用自己,直到堆栈溢出。

您可以通过为自定义包装器类型而不是普通字符串定义生成器来解决此问题(如下所示)。

您将遇到的下一个问题将是空引用异常。当您尝试访问.Length属性时,最初生成的字符串可能是null。可以使用String.length函数来解决这个问题,该函数为null返回0

通过这些更改,您的生成器看起来如下所示:

代码语言:javascript
运行
复制
type Name = Name of string

type NameGen() =
    static member Name() =
        Arb.generate<string * string>
        |> Gen.where (fun (firstName, lastName) ->
            String.length firstName > 0 && String.length lastName > 0
        )
        |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
        |> Arb.fromGen
        |> Arb.convert Name (fun (Name n) -> n)

并且您的属性需要稍微修改一下:

代码语言:javascript
运行
复制
let propertyTests (Name input) =
    let output = toInitials input
    output.EndsWith(".")
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44799465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档