junit-quickcheck:如何以惯用的方式编写生成器

Sti*_*tim 5 java junit quickcheck

junit-quickcheck编写生成器时,可以轻松使用提供的CtorFields反射方法。但是直接在我的业务模型上应用反射会阻止我限制生成的数据(除非我将我的业务模型与快速检查注释交错)。

例如:

class Price {
    public final BigDecimal price;
    public final BigDecimal discountPercentage;
    // With a constructor
}
Run Code Online (Sandbox Code Playgroud)

价格字段可以是任何(合理的)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);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个像这样的生成器:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但我希望能够写这样的东西(没有 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来GeneratorsAPI 更适合内部使用,而不是自定义生成器,例如,configure 方法需要注释 type @InRange,而很难创建该注释的实例。虽然自定义生成器应该主要依赖于反射。(请注意,由于继承的字段,直接将字段放在生成器上是不可能的。)