使用 FsCheck 从 Xunit 测试中删除 Arb.registerByType 的使用
Removing usage of Arb.registerByType from Xunit test using FsCheck
我正在测试 Thoth.Json
编码器/解码器对的往返。
看起来像这样:
type CustomArbitrary =
static member String() =
Arb.Default.String()
|> Arb.filter (not << isNull)
[<Fact>]
let ``Encode.foo Decode.foo round-trip`` () =
let roundTrip (x : Foo) =
let json =
x
|> Encode.foo
|> Encode.toString 2
let decoded =
json
|> Decode.fromString Decode.foo
Ok x = decoded
// Necessary?
Arb.registerByType (typeof<CustomArbitrary>) |> ignore
Check.QuickThrowOnFailure (roundTrip)
如果我不过滤掉 System.String
的 null
值,测试将失败。但是,null
不是 Foo
中的正确值,所以没关系。
但是,由于全局状态等原因,我不喜欢在这里使用 Arb.registerByType
如何重写此测试,以便 Arb.registerByType
不是必需的?
理想情况下,我会设计一次 FsCheck 配置并将其传递给每个测试。
使用原始 FsCheck
像这样创建一次配置:
let config =
{
FsCheck.Config.Default with
Arbitrary = [ typeof<CustomArbitrary> ]
}
然后用它来检查每个测试,如下所示:
Check.One(config, roundTrip)
使用FsCheck.Xunit
如果您切换到 Properties
/Property
而不是 Fact
,您甚至不需要显式 config
实例或 Check
class:
open FsCheck.Xunit
[<Properties(Arbitrary=[| typeof<CustomArbitrary> |])>]
module MyTests =
[<Property>]
let ``Encode.foo Decode.foo round-trip`` (x : Foo) =
let json =
x
|> Encode.foo
|> Encode.toString 2
let decoded =
json
|> Decode.fromString Decode.foo
Ok x = decoded
[<Property>]
let ``Some other test`` () =
true
有关此方法的更多信息 here。
顺便说一句,在测试名称中使用 .
字符时要小心,因为一些测试框架(例如 Visual Studio)使用它们来定义测试层次结构。
我正在测试 Thoth.Json
编码器/解码器对的往返。
看起来像这样:
type CustomArbitrary =
static member String() =
Arb.Default.String()
|> Arb.filter (not << isNull)
[<Fact>]
let ``Encode.foo Decode.foo round-trip`` () =
let roundTrip (x : Foo) =
let json =
x
|> Encode.foo
|> Encode.toString 2
let decoded =
json
|> Decode.fromString Decode.foo
Ok x = decoded
// Necessary?
Arb.registerByType (typeof<CustomArbitrary>) |> ignore
Check.QuickThrowOnFailure (roundTrip)
如果我不过滤掉 System.String
的 null
值,测试将失败。但是,null
不是 Foo
中的正确值,所以没关系。
但是,由于全局状态等原因,我不喜欢在这里使用 Arb.registerByType
如何重写此测试,以便 Arb.registerByType
不是必需的?
理想情况下,我会设计一次 FsCheck 配置并将其传递给每个测试。
使用原始 FsCheck
像这样创建一次配置:
let config =
{
FsCheck.Config.Default with
Arbitrary = [ typeof<CustomArbitrary> ]
}
然后用它来检查每个测试,如下所示:
Check.One(config, roundTrip)
使用FsCheck.Xunit
如果您切换到 Properties
/Property
而不是 Fact
,您甚至不需要显式 config
实例或 Check
class:
open FsCheck.Xunit
[<Properties(Arbitrary=[| typeof<CustomArbitrary> |])>]
module MyTests =
[<Property>]
let ``Encode.foo Decode.foo round-trip`` (x : Foo) =
let json =
x
|> Encode.foo
|> Encode.toString 2
let decoded =
json
|> Decode.fromString Decode.foo
Ok x = decoded
[<Property>]
let ``Some other test`` () =
true
有关此方法的更多信息 here。
顺便说一句,在测试名称中使用 .
字符时要小心,因为一些测试框架(例如 Visual Studio)使用它们来定义测试层次结构。