Это неплохая идея - на самом деле все дело в том, что вы можете это сделать. Генераторы FsCheck полностью композиционны.
Прежде всего обратите внимание, что если у вас есть неизменяемые объекты, конструкторы которых принимают примитивные типы, как выглядит ваш напиток и блюдо, FsCheck может генерировать их из коробки (используя отражение).
let drinkArb = Arb.from<Drink>
let dishArb = Arb.from<Dish>
должен дать вам экземпляр Arbitrary, который является генератором (генерирует случайный экземпляр Drink) и уменьшателем (берет экземпляр Drink и делает его «меньше» — это помогает при отладке, особенно для составных структур, где вы получаете небольшой счетчик -пример, если ваш тест не пройден).
Однако это довольно быстро ломается - в вашем примере вам, вероятно, не нужны отрицательные целые числа для количества напитков или количества блюд. Однако приведенный выше код будет генерировать отрицательные числа. Иногда это легко исправить, если ваш тип действительно представляет собой некую оболочку вокруг другого типа, используя Arb.convert, например.
let drinksArb = Arb.Default.PositiveInt() |> Arb.convert (fun positive -> new Drinks(positive) (fun drinks -> drinks.Amount)
Вам нужно предоставить конверсии в и из в Arb.convert и presto, новый произвольный экземпляр для напитков, который поддерживает ваш инвариант. Конечно, поддерживать другие инварианты может быть не так просто.
После этого становится немного сложнее сгенерировать генератор и термоусадку одновременно из этих двух частей. Всегда начинайте с генератора, затем термоусадочная машина появится позже, если (когда) она вам понадобится. Пример @simonhdickson выглядит разумным. Если у вас есть произвольные экземпляры выше, вы можете получить доступ к их генератору, вызвав .Generator.
let drinksGen = drinksArb.Generator
Если у вас есть генераторы частей (Drink и Dish), вы действительно можете составить их вместе, как предлагает @simonhdickson:
let menuGenerator =
Gen.map3 (fun a b c -> Menu(a,b,c)) (Gen.listOf dishGenerator) (Gen.listOf drinkGenerator) (Arb.generate<int>)
Разделяй и властвуй! В целом, взгляните на то, что intellisense на Gen дает вам некоторые идеи о том, как создавать генераторы.
person
Kurt Schelfthout
schedule
25.02.2014