Как объединить 2 произвольных экземпляра для соответствия сигнатуре метода тестирования

У меня есть функция, которая должна получить два фактических параметра для тестирования. Оба значения должны создаваться экземплярами Arbitrary, поскольку они должны иметь определенную форму, которая не может быть полностью произвольной.
Итак, я создаю следующий код.

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

Но как мне теперь объединить эти 2 произвольных экземпляра, чтобы они совпадали с сигнатурой тестового метода?

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

Check.QuickThrowOnFailure prop

person robkuz    schedule 06.10.2016    source источник


Ответы (1)


Учитывая два типа, SomeTypeA и SomeTypeB:

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'.

Вам также необходимо позаботиться о том, чтобы сигнатура метода тестирования теперь отражала созданный Arbitrary, становясь (некарриентной) функцией для пар.

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

Как работает пример:

  • Выражение вычисления gen создает генератор типа Gen<SomeTypeA * SomeTypeB>
  • Экземпляр Arbitrary<SomeTypeA * SomeTypeB> создается из этого генератора
  • Наконец, свойство (QuickCheck/FsCheck) создается из произвольного файла via Prop.forAll.

Это всегда один и тот же путь:

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

Надеюсь, это поможет.

person Nikos Baxevanis    schedule 06.10.2016