如何组合2个任意实例以匹配测试方法签名

时间:2016-10-06 12:01:36

标签: f# fscheck

我有一个功能,应该获得两个实际参数进行测试。 这两个值都应由任意实例创建,因为它们需要具有完全任意的良好形式 所以我创建了以下代码

let updating (x:SomeType) (y:SomeOtherType) =
    let result = update x y
    result.someProp = x.someProp
    && result.otherProp = y.otherProp

let arbSomeType = 
    Arb.generate<SomeType> 
        |> Gen.filter fun x -> x.checkSomeStuff
        |> Arb.fromGen

let arbSomeType = 
    Arb.generate<SomeOtherType> 
        |> Gen.filter fun x -> x.checkPropertiesOfThis
        |> Arb.fromGen

但是,我现在如何组合这两个任意实例,以便它们与测试方法的签名相匹配?

//let prop = Prop.forAll arbSomeType + arbSomeType updating

Check.QuickThrowOnFailure prop

1 个答案:

答案 0 :(得分:6)

有两种类型,SomeTypeASomeTypeB

type SomeTypeA = 
    { A : obj }

type SomeTypeB = 
    { B : obj }

您可以创建Property,其中输入是这两种类型,如下所示:

let prop =
    gen { let! a = Arb.generate<SomeTypeA>
          let! b = Arb.generate<SomeTypeB>
          return a, b }
    |> Arb.fromGen
    |> Prop.forAll
    <| fun (a, b) ->
        // 'a' is SomeTypeA
        // 'b' is SomeTypeB
        true // Dummy - replace with whatever you want to do with 'a' and 'b'.

您还需要注意,测试方法的签名现在反映了创建的任意 - 成对的(未发布的)函数。

// instead of
let updating (x:SomeType) (y:SomeOtherType) = ...
// do this
let updating (x:SomeType, y:SomeOtherType) = ...

示例如何运作

  • gen计算表达式创建类型为Gen<SomeTypeA * SomeTypeB>
  • 的生成器
  • 从该生成器
  • 创建Arbitrary<SomeTypeA * SomeTypeB>实例
  • 最后,通过Prop.forAll
  • 从任意位置创建(QuickCheck / FsCheck)属性

它总是一样的道路:

Generator[/optional Shrinker] -> Arbitrary -> Property -> <your_code>

希望有所帮助。