测试函数返回选项<T>
Testing functions returning option<T>
考虑对将 strings of constrained length 定义为表示用户名的类型的模块进行单元测试:
module UserName
type T = UserName of string
let create (userName : string) =
if userName.Length >= 6 && userName.Length <= 16
then Some (UserName userName)
else None
let apply f (UserName userName) = f userName
let value userName = apply id userName
确保函数 returns None
用于无效输入的单元测试看起来很简单:
[<Fact>]
let ``UserName must have at least six characters`` () =
UserName.create "aaa" |> should equal None
但是,当函数 returns Some
似乎需要额外的一行来确保 match
表达式的完整性时,单元测试:
[<Fact>]
let ``Valid UserName`` () =
match UserName.create "validname" with
| Some result ->
UserName.value result |> should equal "validname"
| None -> Assert.True(false)
这对我来说不合适,因为我的测试必须定义代码来测试无论如何都必须产生失败的“不愉快”路径。
我希望我能改写这个
[<Fact>]
let ``Valid UserName`` () =
UserName.create "validname" |> should equal (Some (UserName "validname"))
但它不编译(值或构造函数 'UserName' 未定义)。
有没有一种方法可以编写返回 option<T>
的函数的单元测试,而无需显式检查“不愉快”路径(例如 | None -> Assert.True(false)
)?我愿意向 UserName
模块添加更多类型 and/or 函数以使其更易于测试。
将value
应用到Some
里面,然后比较:
UserName.create "validname"
|> Option.map UserName.value
|> should equal (Some "validname")
考虑对将 strings of constrained length 定义为表示用户名的类型的模块进行单元测试:
module UserName
type T = UserName of string
let create (userName : string) =
if userName.Length >= 6 && userName.Length <= 16
then Some (UserName userName)
else None
let apply f (UserName userName) = f userName
let value userName = apply id userName
确保函数 returns None
用于无效输入的单元测试看起来很简单:
[<Fact>]
let ``UserName must have at least six characters`` () =
UserName.create "aaa" |> should equal None
但是,当函数 returns Some
似乎需要额外的一行来确保 match
表达式的完整性时,单元测试:
[<Fact>]
let ``Valid UserName`` () =
match UserName.create "validname" with
| Some result ->
UserName.value result |> should equal "validname"
| None -> Assert.True(false)
这对我来说不合适,因为我的测试必须定义代码来测试无论如何都必须产生失败的“不愉快”路径。
我希望我能改写这个
[<Fact>]
let ``Valid UserName`` () =
UserName.create "validname" |> should equal (Some (UserName "validname"))
但它不编译(值或构造函数 'UserName' 未定义)。
有没有一种方法可以编写返回 option<T>
的函数的单元测试,而无需显式检查“不愉快”路径(例如 | None -> Assert.True(false)
)?我愿意向 UserName
模块添加更多类型 and/or 函数以使其更易于测试。
将value
应用到Some
里面,然后比较:
UserName.create "validname"
|> Option.map UserName.value
|> should equal (Some "validname")