junit-quickcheck: как писать генераторы идиоматическим способом

При написании генератора для junit-quickcheck легко использовать Ctor или же Fields методы отражения предоставляются. Но применение отражения непосредственно к моим бизнес-моделям не позволяет мне ограничивать сгенерированные данные (если я не чередую свои бизнес-модели с аннотациями quickcheck).

Например:

class Price {
    public final BigDecimal price;
    public final BigDecimal discountPercentage;
    // With a constructor
}

Поле цены может быть любым (разумным) BigDecimal (скажем, до 1000), но скидка должна быть от 0 до 100.

Как написать генератор идиоматическим способом?

Мой текущий подход заключается в создании класса, который определяет модель для генерации:

class PriceFields {
    public @InRange(max="1000") BigDecimal price;
    public @InRange(max="100") BigDecimal discountPercentage;

    public Price toPrice(){
        return new Price(price, discountPercentage);
    }
}

И генератор, как это:

public class PriceGenerator extends Generator<Price> {
    public PriceGenerator() {
        super(Price.class);
    }

    @Override
    public Price generate(SourceOfRandomness random, GenerationStatus status) {
        return gen().fieldsOf(PriceFields.class)
            .generate(random, status)
            .toPrice();
    }
}

Но я хотел бы иметь возможность написать что-то вроде этого (без класса PriceFields):

public class PriceGenerator extends Generator<Price> {
    public PriceGenerator() {
        super(Price.class);
    }

    @Override
    public Price generate(SourceOfRandomness random, GenerationStatus status) {
        BigDecimal price = gen().???; // How to generate this constrained BigDecimal?
        BigDecimal percentage = gen().???; // How to generate this constrained BigDecimal?
        return new Price(price, percentage);
    }
}

Кажется, как будто Generators API больше предназначен для внутреннего использования, чем для пользовательских генераторов, например, метод configure ожидает тип аннотации @InRange, который трудно создать экземпляр. В то время как нестандартные генераторы должны полагаться в основном на рефлексию. (Обратите внимание, что непосредственное размещение полей в Генераторе невозможно из-за унаследованных полей.)

0 ответов

Другие вопросы по тегам