简体   繁体   中英

Removing usage of Arb.registerByType from Xunit test using FsCheck

I am testing a round-trip of a Thoth.Json Encoder / Decoder pair.

It looks like this:

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)

The test fails if I do not filter out null values for System.String . However, null is not a proper value inside Foo so that is fine.

However, I don't like the usage of Arb.registerByType here due to global state etc.

How can I rewrite this test so that Arb.registerByType is not necessary?

Ideally, I would design a FsCheck config once and pass that to each test.

Using vanilla FsCheck

Create the config once like this:

let config =
    {
        FsCheck.Config.Default with
            Arbitrary = [ typeof<CustomArbitrary> ]
    }

Then use it to check each test like this:

Check.One(config, roundTrip)

Using FsCheck.Xunit

If you switch to Properties / Property instead of Fact , you don't even need an explicit config instance or the 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

More info on this approach here .

By the way, be careful about using . characters in your test names, because some test frameworks (eg Visual Studio) use them to define a test hierarchy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM